/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "随机数.h"

#include "../Surface.h"
#include "../面.h"
#include "引擎数据类型.h"
#include "UI/UI主题.h"
#include "面/几何模型生成.h"

#include "底层绘图/intern/绘图框架.h"
#include "底层绘图/intern/Vulkan/Vulkan框架.h"
#include "底层绘图/intern/Vulkan/buffer/Vk缓存.h"

#include <公共函数.h>

#include "MBT_Engine.h"


static void f_vg_记录图元(S_2D画布* s, S_材质管线* 材质) {
	++s->m_绘制推进层;

	if (s->m_绘制推进层 >= s->m_surf.size()) {
		S_Surface2D face = {};
		f_initSurface2D(&face, s->m_Ctx);
		s->m_surf.push_back(face);
	}
	s->m_surf[s->m_绘制推进层].m_笔刷.g_材质 = 材质;
}




uint16 f_vg_gen属性(S_2D画布* s) {
	S_板载缓存* 属性 = f_buf_create板载缓存(s->m_Ctx, sizeof(S_2D_PanelAttr), E_板载缓存类型::e_UBO, 1);

	S_2D_PanelAttr p = {};
	p.m_Scale = {1,1};

	f_buf_fill板载缓存<S_2D_PanelAttr>(属性, { p }, E_板载缓存类型::e_UBO);
	s->m_属性.push_back(属性);

	return s->m_属性.size() - 1;
}

uint16 f_vg_gen渐变梯度(S_2D画布* s) {
	S_板载缓存* 梯度 = f_buf_create板载缓存(s->m_Ctx, sizeof(vec2));
	f_buf_fill板载缓存<vec2>(梯度, {{0, 0}}, E_板载缓存类型::e_SSBO);
	s->m_扩展GPU参数.push_back(梯度);
	return s->m_扩展GPU参数.size() - 1;
}

S_板载缓存* f_vg_gen曲线(S_2D画布* s) {
	S_板载缓存* buf = f_buf_create板载缓存(s->m_Ctx, sizeof(S_CurvePoint2), E_板载缓存类型::e_SSBO);
	S_CurvePoint2 data = { {}, {}, 0, 0 };
	f_buf_fill板载缓存(buf, sizeof(S_CurvePoint2), 1, &data, E_板载缓存类型::e_SSBO);
	return buf;
}

S_板载缓存* f_vg_gen曲线点索引(S_2D画布* s) {
	S_板载缓存* buf = f_buf_create板载缓存(s->m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO);
	uint32 data = 0;
	f_buf_fill板载缓存(buf, sizeof(uint32), 1, &data, E_板载缓存类型::e_SSBO);
	return buf;
}

S_板载缓存* f_vg_gen颜色256(S_2D画布* s) {
	S_板载缓存* buf = f_buf_create板载缓存(s->m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO);
	f_buf_fill板载缓存<uint32>(buf, {{}}, E_板载缓存类型::e_SSBO);
	return buf;
}

S_板载缓存* f_vg_gen属性(S_设备环境& m_Ctx) {
	S_板载缓存* 属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_2D_PanelAttr), E_板载缓存类型::e_UBO, 1);

	S_2D_PanelAttr p = {};
	p.m_Scale = { 1,1 };
	f_buf_fill板载缓存<S_2D_PanelAttr>(属性, { p }, E_板载缓存类型::e_UBO);

	return 属性;
}

S_GPU内存块* f_vg_gen2D变换(S_2D画布* s, uint32 num) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包变换, 1);
	return 块;
}

S_GPU内存块* f_vg_gen2D颜色(S_2D画布* s, uint32 num) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包颜色, 1);
	return 块;
}

S_GPU内存块* f_vg_gen线属性a(S_2D画布* s) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包线属性, 1);
	return 块;
}

S_GPU内存块* f_vg_gen色轮属性(S_设备环境& m_Ctx) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包色轮属性, 1);
	return 块;
}

S_GPU内存块* f_vg_gen渐变控制(S_设备环境& m_Ctx) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包渐变控制属性, 1);
	return 块;
}

S_GPU内存块* f_vg_gen渐变属性(S_设备环境& m_Ctx) {
	S_GPU内存块* 块 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*块) = f_bm_alloc(S_2D画布::g凸包渐变属性, 1);
	return 块;
}












//uint16 f_vg_gen单色凸边形填充(S_2D画布* s, uint16 图元, uint16 变换, uint16 颜色, uint16 属性) {
//	f_vg_记录图元(s, s->m_调色板->m_单色凸边形填充);
//	
//	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
//	{
//		f_alloc_笔刷槽数量(e, 5);
//
//		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
//		else e.m_参数槽[0] = s->m_属性[属性];
//		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
//		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
//		e.m_参数槽[3] = S_2D画布::m_间接绘制图元顶点;
//		e.m_参数槽[4] = s->m_扩展GPU参数[图元];
//
//		e.m_绑定位置[0] = 0;
//		e.m_绑定位置[1] = 1;
//		e.m_绑定位置[2] = 2;
//		e.m_绑定位置[3] = 3;
//		e.m_绑定位置[4] = 4;
//
//		s->m_surf[s->m_绘制推进层].m_笔刷.m_纹理信息 = 0;
//		s->m_surf[s->m_绘制推进层].m_笔刷.m_纹理参数数量 = 0;
//	}
//	
//	s->m_surf[s->m_绘制推进层].m_线宽 = 1.0;
//
//	return s->m_绘制推进层;
//}

uint16 f_vg_gen刻度线(S_2D画布* s, uint16 属性, float32 线宽) {
	f_vg_记录图元(s, s->m_调色板->m_刻度线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 3);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		
		e.m_参数槽[1] = S_2D画布::g图标变换;
		e.m_参数槽[2] = S_2D画布::g图标颜色;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;
	}
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, 4096);
	auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
	for (uint32 i = 0; i < 2048; ++i) {
		v[i * 2    ].coord = { float32(i), 0 };
		v[i * 2 + 1].coord = { float32(i), 1 };
	}
	return s->m_绘制推进层;
}

S_凸边图元 f_vg_gen凸边图元(S_2D画布* s, const S_凸边图元& 链接元素) {
	S_凸边图元 图元{};

	if (链接元素.属性) {
		图元.属性 = 链接元素.属性;
		图元.链接属性 = true;
	}
	else {
		图元.属性 = f_vg_gen属性(s->m_Ctx);
		图元.链接属性 = false;
	}

	if (链接元素.变换) {
		图元.变换 = 链接元素.变换;
		图元.链接变换 = true;
	}
	else {
		图元.变换 = f_vg_gen2D变换(s);
		图元.链接变换 = false;
	}

	if (链接元素.颜色) {
		图元.颜色 = 链接元素.颜色;
		图元.链接颜色 = true;
	}
	else {
		图元.颜色 = f_vg_gen2D颜色(s);
		图元.链接颜色 = false;
	}

	if (链接元素.线属性) {
		图元.线属性 = 链接元素.线属性;
		图元.链接线属性 = true;
	}
	else {
		图元.线属性 = f_vg_gen线属性a(s);
		图元.链接线属性 = false;
	}

	return 图元;
}

S_渐变图元 f_vg_gen渐变图元(S_2D画布* s, const S_渐变图元& 链接元素) {
	S_渐变图元 图元{};

	if (链接元素.属性) {
		图元.属性 = 链接元素.属性;
		图元.链接属性 = true;
	}
	else {
		图元.属性 = f_vg_gen属性(s->m_Ctx);
		图元.链接属性 = false;
	}

	if (链接元素.变换) {
		图元.变换 = 链接元素.变换;
		图元.链接变换 = true;
	}
	else {
		图元.变换 = f_vg_gen2D变换(s);
		图元.链接变换 = false;
	}

	if (链接元素.颜色) {
		图元.颜色 = 链接元素.颜色;
		图元.链接颜色 = true;
	}
	else {
		图元.颜色 = f_vg_gen渐变控制(s->m_Ctx);
		图元.链接颜色 = false;
	}

	if (链接元素.渐变) {
		图元.渐变 = 链接元素.渐变;
		图元.链接渐变 = true;
	}
	else {
		图元.渐变 = f_vg_gen渐变属性(s->m_Ctx);
		图元.链接渐变 = false;
	}
	return 图元;
}


uint16 f_vg_画行文本(S_2D画布* s, uint16 字体ID, uint16 变换, uint16 颜色, uint16 属性, uint16 字号, std::string 字体名称) {
	f_vg_记录图元(s, s->m_调色板->m_文本笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		auto key = 字体名称 + "_" + f_整数值转字符串(字号);
		auto& tex = s->m_调色板->m_Fonts[key];

		f_alloc_笔刷槽数量(e, 5);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_参数槽[3] = s->m_扩展GPU参数[字体ID];
		e.m_绑定位置[3] = DEF_BINDING_WIDGET_TextCoordID;

		e.m_参数槽[4] = tex.m_uv偏移;
		e.m_绑定位置[4] = DEF_BINDING_WIDGET_TextCoord;


		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		//e.m_纹理参数数量 = 1;
		e.m_纹理信息[0] = tex.m_Tex;
		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;

		s->m_surf[s->m_绘制推进层].m_纹理 = key;
	}

	return s->m_绘制推进层;
}

uint16 f_vg_画行文本(S_2D画布* s, S_板载缓存* 字ID, S_板载缓存* 变换, S_板载缓存* 颜色, uint16 属性, const S_Font& 字体) {
	f_vg_记录图元(s, s->m_调色板->m_文本笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		auto& font = 字体;
		f_alloc_笔刷槽数量(e, 5);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = 变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = 颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_参数槽[3] = 字ID;
		e.m_绑定位置[3] = DEF_BINDING_WIDGET_TextCoordID;

		e.m_参数槽[4] = font.m_uv偏移;
		e.m_绑定位置[4] = DEF_BINDING_WIDGET_TextCoord;


		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		e.m_纹理信息[0] = font.m_Tex;
		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;

		s->m_surf[s->m_绘制推进层].m_纹理 = font.m_字体名称;
		
	}

	return s->m_绘制推进层;
}

uint16 f_vg_画间接凸边形(S_2D画布* s, S_凸边图元& 图元, E_填充模式 模式, float32 线宽) {
	
	switch (模式) {
	case e_条纹:
	case E_填充模式::e_填充面: {
		f_vg_记录图元(s, s->m_调色板->m_间接单色填充);
		auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;

		f_alloc_笔刷槽数量(e, 3);

		
		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 图元.属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		
		e.m_参数槽[1] = S_2D画布::g凸包变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = S_2D画布::g凸包颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;


		e.m_纹理信息 = nullptr;
		e.m_纹理参数数量 = 0;
		break;
	}
		
	case E_填充模式::e_填充线: {
		f_vg_记录图元(s, s->m_调色板->m_间接单色描边);
		auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;

		f_alloc_笔刷槽数量(e, 4);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 图元.属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		
		e.m_参数槽[1] = S_2D画布::g凸包变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = S_2D画布::g凸包颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_参数槽[3] = S_2D画布::g凸包线属性;
		e.m_绑定位置[3] = DEF_BINDING_WIDGET_LineProp;


		e.m_纹理信息 = nullptr;
		e.m_纹理参数数量 = 0;
		break;
	}

	}
	
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;
	图元.层 = s->m_绘制推进层;

	return s->m_绘制推进层;
}

uint16 f_vg_画园公切线链接线(S_2D画布* s, uint16 属性, float32 线宽) {
	f_vg_记录图元(s, s->m_调色板->m_公切园链接线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;

	f_alloc_笔刷槽数量(e, 2);

	if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
	else e.m_参数槽[0] = s->m_属性[属性];
	e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

	e.m_参数槽[1] = S_2D画布::g线段;
	e.m_绑定位置[1] = DEF_BINDING_WIDGET_CurvePoint;

	e.m_纹理信息 = nullptr;
	e.m_纹理参数数量 = 0;

	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}


//uint16 f_vg_画条纹纹理(S_2D画布* s, S_凸边图元& 图元, E_填充模式 模式) {
//	f_vg_记录图元(s, s->m_调色板->m_条纹填充);
//	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
//	{
//		f_alloc_笔刷槽数量(e, 4);
//
//		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
//		else e.m_参数槽[0] = 图元.属性;
//		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
//		
//		e.m_参数槽[1] = S_2D画布::g凸包变换;
//		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
//		e.m_参数槽[2] = S_2D画布::g凸包颜色;
//		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;
//		e.m_参数槽[3] = S_2D画布::g凸包线属性;
//		e.m_绑定位置[3] = DEF_BINDING_WIDGET_LineProp;
//	}
//
//	图元.层 = s->m_绘制推进层;
//	return s->m_绘制推进层;
//}

uint16 f_vg_画色轮(S_2D画布* s, S_凸边图元& 图元) {
	f_vg_记录图元(s, s->m_调色板->m_色轮);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 图元.属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g凸包变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
		e.m_参数槽[2] = S_2D画布::g凸包颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;
	}

	图元.层 = s->m_绘制推进层;
	return s->m_绘制推进层;
}

uint16 f_vg_画渐变(S_2D画布* s, S_凸边图元& 图元) {
	f_vg_记录图元(s, s->m_调色板->m_渐变);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 4);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 图元.属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g凸包变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = S_2D画布::g凸包颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_参数槽[3] = S_2D画布::g凸包线属性;
		e.m_绑定位置[3] = DEF_BINDING_WIDGET_LineProp;
	}

	图元.层 = s->m_绘制推进层;
	return s->m_绘制推进层;
}


uint16 f_vg_画动态线(S_2D画布* s, uint16 属性, float32 线宽) {
	f_vg_记录图元(s, s->m_调色板->m_动态线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数槽 = (S_板载缓存**)calloc(3, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(3, sizeof(uint8));
		//e.m_参数元素数量 = 3;
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		e.m_参数槽[1] = S_2D画布::g图标变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
		e.m_参数槽[2] = S_2D画布::g图标颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;


		e.m_纹理信息 = nullptr;
		e.m_纹理参数数量 = 0;
	}
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	
	return s->m_绘制推进层;
}

uint16 f_vg_画网格刻度线(S_2D画布* s, uint16 属性, float32 线宽) {
	f_vg_记录图元(s, s->m_调色板->m_网格刻度线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		
		e.m_参数槽[1] = S_2D画布::g图标变换;
		e.m_参数槽[2] = S_2D画布::g图标颜色;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;
	}
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, (2048*6));
	auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
	for (uint32 i = 0; i < 2048*6; ++i) {
		v[i] = { float32(i), 0 };
		v[i].coord = { float32(i), 1 };
	}
	s->m_surf[s->m_绘制推进层].m_顶点偏移 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_偏移;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_数量;
	
	return s->m_绘制推进层;
}

uint16 f_vg_画曲线点(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点) {
	f_vg_记录图元(s, s->m_调色板->m_曲线点);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 2);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = 曲线点;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_CurvePoint;
		
		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;

	}
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	

	return s->m_绘制推进层;
}

uint16 f_vg_画曲线(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点, S_板载缓存* 曲线点ID, float32 线宽) {
	f_vg_记录图元(s, s->m_调色板->m_曲线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 2);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;
		
		e.m_参数槽[1] = 曲线点;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_CurvePoint;

		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;
	}
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}

uint16 f_vg_画曲线(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点, float32 线宽, bool 多曲线) {
	if (多曲线) {
		f_vg_记录图元(s, s->m_调色板->m_多曲线);
	}
	else {
		f_vg_记录图元(s, s->m_调色板->m_曲线);
	}
	
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 2);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = 曲线点;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_CurvePoint;

		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;
	}
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}

uint16 f_vg_画噪波(S_2D画布* s, uint16 属性) {
	f_vg_记录图元(s, s->m_调色板->m_过程纹理填充);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 3);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g纹理变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = f_buf_getGlobal().g_纹理属性;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_TexProp;
	}
	return s->m_绘制推进层;
}

uint16 f_vg_画纹理(S_2D画布* s, uint16 属性, S_纹理* 纹理) {
	f_vg_记录图元(s, s->m_调色板->m_单纹理);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 2);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g纹理变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		e.m_纹理信息[0] = 纹理;
		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;
	}

	return s->m_绘制推进层;
}

uint16 f_vg_画多纹理(S_2D画布* s, uint16 属性, S_纹理集* 纹理, const S_MulTex_ConstPush* cp) {
	f_vg_记录图元(s, s->m_调色板->m_多纹理);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		f_alloc_笔刷槽数量(e, 4);
		
		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g纹理变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = f_buf_getGlobal().m_UI32动态属性;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_TextureID;
		e.m_参数类型[2] = E_板载缓存类型::e_SSBO;

		e.m_参数槽[3] = 纹理;
		e.m_绑定位置[3] = DEF_BINDING_WIDGET_Texture;
		e.m_参数类型[3] = E_板载缓存类型::e_SAMPLER_Array;

		e.m_常量属性 = cp;
	}
	return s->m_绘制推进层;
}

uint16 f_vg_画表格(S_2D画布* s, S_板载缓存* 属性) {
	f_vg_记录图元(s, s->m_调色板->m_表格线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g表格变换GPU缓存;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = S_2D画布::g表格颜色GPU缓存;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

	}

	return s->m_绘制推进层;
}

uint16 f_vg_画矢量线(S_2D画布* s, S_板载缓存* 属性) {
	f_vg_记录图元(s, s->m_调色板->m_矢量线);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = 属性;
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = S_2D画布::g表格变换GPU缓存;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = S_2D画布::g表格颜色GPU缓存;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;
	}
	return s->m_绘制推进层;
}


S_2D笔刷 f_vg_gen单色阴影(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性) {
	f_vg_记录图元(s, s->m_调色板->m_边缘阴影);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 3);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		//e.m_参数元素[0] = s->m_属性[属性];
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
		e.m_绑定位置[0] = 0;
		e.m_绑定位置[1] = 1;
		e.m_绑定位置[2] = 2;

		e.m_纹理信息 = 0;
		e.m_纹理参数数量 = 0;
	}

	return e;
}




S_2D笔刷 f_vg_gen图像笔刷(S_2D画布* s, uint16 变换, uint16 属性, S_纹理* 纹理) {
	f_vg_记录图元(s, s->m_调色板->m_外部纹理填充);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 2;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 2);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_绑定位置[0] = 0;
		e.m_绑定位置[1] = 1;
		
		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		e.m_纹理信息[0] = 纹理;
		if(纹理) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;
		//e.m_纹理库对象 = &(s->m_调色板->m_ICOs[group]);
		
	}

	return e;
}

S_2D文本对象 f_vg_gen文本笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 字体ID, std::string 字体名称, uint16 字号)  {
	f_vg_记录图元(s, s->m_调色板->m_文本笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		auto key = 字体名称 + "_" + f_整数值转字符串(字号);
		auto& tex = s->m_调色板->m_Fonts[key];

		//e.m_参数元素数量 = 5;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 5);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
		e.m_参数槽[3] = s->m_扩展GPU参数[字体ID];
		e.m_参数槽[4] = tex.m_uv偏移;
		e.m_绑定位置[0] = 0;
		e.m_绑定位置[1] = 1;
		e.m_绑定位置[2] = 2;
		e.m_绑定位置[3] = 3;
		e.m_绑定位置[4] = 4;

		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		//e.m_纹理参数数量 = 1;
		e.m_纹理信息[0] = tex.m_Tex;
		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		} else e.m_纹理参数数量 = 0;
		
		//e.m_纹理库对象 = key;
		s->m_surf[s->m_绘制推进层].m_纹理 = key;
	}

	return { &e, 字体ID };
}

S_2D笔刷 f_vg_gen文本块笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, const S_Font& 字体) {
	f_vg_记录图元(s, s->m_调色板->m_文本块笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 4;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 4);


		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
		e.m_参数槽[3] = 字体.m_uv偏移;
		//e.m_参数元素[4] = s->m_扩展GPU参数[内部编码ID];
		e.m_绑定位置[0] = 0;
		e.m_绑定位置[1] = 1;
		e.m_绑定位置[2] = 2;
		e.m_绑定位置[3] = 3;


		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		//e.m_纹理参数数量 = 1;
		e.m_纹理信息[0] = 字体.m_Tex;
		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;
	}

	return e;
}

S_2D笔刷 f_vg_gen连接点笔(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 配置) {
	f_vg_记录图元(s, s->m_调色板->m_连接点笔);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;

	{
		//e.m_参数槽 = (S_板载缓存**)calloc(4, sizeof(S_板载缓存*));
		//e.m_参数元素数量 = 4;
		f_alloc_笔刷槽数量(e, 4);

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_参数槽[1] = s->m_扩展GPU参数[变换];
		e.m_参数槽[2] = s->m_扩展GPU参数[颜色];
		e.m_参数槽[3] = s->m_扩展GPU参数[配置];
	}
	
	return e;
}







uint16 f_vg_绘制矩形(S_2D画布* s, S_2D笔刷& 笔刷, const vec4& point, bool 是否填充, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	if(是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);

	f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, 4);
	auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
	//std::vector<S_2D元素顶点> v(4);
	v[0].coord.x = point.x;
	v[2].coord.x = point.x;

	v[0].coord.y = point.y;
	v[1].coord.y = point.y;

	v[1].coord.x = point.z;
	v[3].coord.x = point.z;

	v[2].coord.y = point.w;
	v[3].coord.y = point.w;


	v[0].weights.x = 0.0;
	v[0].weights.y = 0.0;
	//C[0].z = 1.0;

	v[1].weights.x = 1.0;
	v[1].weights.y = 0.0;
	//C[1].z = 1.0;

	v[2].weights.x = 0.0;
	v[2].weights.y = 1.0;
	//C[2].z = 1.0;

	v[3].weights.x = 1.0;
	v[3].weights.y = 1.0;
	//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, v);
	//s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点->m_Size;
	
	return s->m_绘制推进层;
}

uint16 f_vg_绘制矩形(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否填充, float32 线宽, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);

	
	if (是否填充) {
		f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, 4);
		auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
		//std::vector<S_2D元素顶点> v(4);
		v[0].coord.x = 0;
		v[0].coord.y = 0;

		v[1].coord.x = 1;
		v[1].coord.y = 0;

		v[2].coord.x = 0;
		v[2].coord.y = 1;
		
		v[3].coord.x = 1;
		v[3].coord.y = 1;



		v[0].weights.x = 0.0;
		v[0].weights.y = 0.0;
		//C[0].z = 1.0;
		v[1].weights.x = 1.0;
		v[1].weights.y = 0.0;
		//C[1].z = 1.0;
		v[2].weights.x = 0.0;
		v[2].weights.y = 1.0;
		//C[2].z = 1.0;
		v[3].weights.x = 1.0;
		v[3].weights.y = 1.0;

		//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, v);
	} else {
		//std::vector<S_2D图元顶点> v(4);
		f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, 5);
		auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);

		v[0].coord.x = 0;
		v[0].coord.y = 0;

		v[1].coord.x = 1;
		v[1].coord.y = 0;

		v[2].coord.x = 1;
		v[2].coord.y = 1;

		v[3].coord.x = 0;
		v[3].coord.y = 1;


		v[0].weights.x = 0.0;
		v[0].weights.y = 0.0;
		//C[0].z = 1.0;
		v[1].weights.x = 1.0;
		v[1].weights.y = 0.0;
		//C[1].z = 1.0;
		v[2].weights.x = 1.0;
		v[2].weights.y = 1.0;
		//C[2].z = 1.0;
		v[3].weights.x = 0.0;
		v[3].weights.y = 1.0;


		v[4] = v[3];
		//v.push_back(v.front());
		//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, v);
	}

	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_数量;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;
	return s->m_绘制推进层;
}

//uint16 f_vg_绘制线(S_2D画布* s, const std::vector<vec2>& point, float32 线宽, bool 是否开始新图元) {
//	
//	f_vg_记录图元(s, s->m_调色板->m_单色描边);
//	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
//
//	uint32 num = point.size();
//	//std::vector<S_2D图元顶点> 线(num);
//	f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, num);
//	auto* v = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
//	for (uint32 i = 0; i < num; ++i) {
//		//uv[i] = { point[i].x, point[i].y, 1.0f };
//		v[i].coord = point[i];
//		v[i].weights = point[i];
//	}
//	//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, 线);
//	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_数量;
//	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;
//
//	return s->m_绘制推进层;
//}




inline uint32 f_构建圆角矩形顶点(std::vector<S_2D图元顶点>& vert, float32 半径, bool 是否填充) {
	uint32 num = uint32(DEF_Max(半径, 8) / 2) * 2;
	std::vector<vec2> temp(num);
	f_计算圆坐标2({ 0.0, 0.0 }, 0.5, num, temp.data());
	temp.push_back(temp.front());

	uint32 n = num / 4;
	uint32 圆角点数量 = (n + 1);

	vert.resize(圆角点数量 * 4);

	if (是否填充) {
		//vert.resize(圆角点数量 * 4);
		for (uint32 i = 0; i < 圆角点数量; ++i) {
			vert[i * 2].coord = temp[i] + 0.5;
			vert[i * 2 + 1].coord = temp[n * 4 - i] + 0.5;

			vert[i * 2 + 圆角点数量 * 2].coord = temp[n + i] + 0.5;
			vert[i * 2 + 圆角点数量 * 2 + 1].coord = temp[n * 3 - i] + 0.5;
		}


		for (uint32 i = 0; i < 圆角点数量; ++i) {
			vert[i * 2].normal = { 1.0f, 1.0f };
			vert[i * 2 + 1].normal = { 0.0, 1.0 };
			vert[i * 2 + 圆角点数量 * 2].normal = { 1.0, 0.0 };
			vert[i * 2 + 圆角点数量 * 2 + 1].normal = { 0.0,0.0 };
		}

	}
	else {
		//vert.resize(圆角点数量 * 4);
		for (uint32 i = 0; i < 4; ++i) {
			for (uint32 j = 0; j < 圆角点数量; ++j) {
				vert[i * 圆角点数量 + j].coord = temp[i * n + j] + 0.5;
			}
		}
		for (uint32 i = 0; i < 圆角点数量; ++i) {
			vert[i].weights = { 1.0f, 1.0f };
			vert[圆角点数量 + i].weights = { 1.0, 0.0 };
			vert[圆角点数量 * 2 + i].weights = { 0.0, 0.0 };
			vert[圆角点数量 * 3 + i].weights = { 0.0,1.0 };
		}

		

	}

	return 圆角点数量;
}

uint16 f_vg_绘制圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, const vec4& point, float32 半径, bool 是否填充, float32 线宽, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);

	uint32 num = uint32(DEF_Max(半径, 8) / 2) * 2;
	std::vector<vec2> temp(num);
	f_计算圆坐标2({0.0, 0.0}, 半径, num, temp.data());
	temp.push_back(temp.front());

	uint32 n = num / 4;
	uint32 圆角点数量 = (n + 1);
	
	//std::vector<vec2> C(圆角点数量 * 4);
	f_bm_resize(s->m_surf[s->m_绘制推进层].m_顶点, 圆角点数量 * 4);
	auto* 圆角矩形 = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);

	if (是否填充) {
		
		//std::vector<S_2D元素顶点> 圆角矩形(圆角点数量 * 4);

		for (uint32 i = 0; i < 圆角点数量; ++i) {
			圆角矩形[i * 2 ].coord = temp[i] + 半径;
			圆角矩形[i * 2 + 1].coord = temp[n * 4 - i] + 半径;

			圆角矩形[i * 2 + 圆角点数量 * 2].coord = temp[n + i] + 半径;
			圆角矩形[i * 2 + 圆角点数量 * 2 + 1].coord = temp[n*3 - i] + 半径;
		}
		

		for (uint32 i = 0; i < 圆角点数量; ++i) {
			圆角矩形[i * 2].weights = { 1.0f, 1.0f };
			//C[i * 2].z = 半径*2;

			圆角矩形[i * 2 + 1].weights = { 0.0, 1.0 };
			//C[i * 2 + 1].z = 半径*2;

			圆角矩形[i * 2 + 圆角点数量 * 2].weights = { 1.0, 0.0 };
			//C[i * 2 + 圆角点数量 * 2].z = 半径*2;

			圆角矩形[i * 2 + 圆角点数量 * 2 + 1].weights = { 0.0,0.0 };
			//C[i * 2 + 圆角点数量 * 2 + 1].z = 半径*2;
		}

	}
	else {
		std::vector<S_2D图元顶点> 圆角矩形(圆角点数量 * 4);

		for (uint32 i = 0; i < 4; ++i) {
			for (uint32 j = 0; j < 圆角点数量; ++j) {
				圆角矩形[i * 圆角点数量 + j].coord = temp[i*n+j] + 半径;
			}
		}
		for (uint32 i = 0; i < 圆角点数量; ++i) {
			圆角矩形[i].weights = { 1.0f, 1.0f };
			
			圆角矩形[圆角点数量 + i].weights = { 1.0, 0.0 };
			
			圆角矩形[圆角点数量 * 2 + i].weights = { 0.0, 0.0 };
			
			圆角矩形[圆角点数量 * 3 + i].weights = { 0.0,1.0 };
		}

		圆角矩形.insert(圆角矩形.begin(), 圆角矩形.back());
		圆角矩形.push_back(圆角矩形[1]);
		圆角矩形.push_back(圆角矩形[2]);
		//圆角矩形.push_back(圆角矩形[3]);
		//圆角矩形.push_back(圆角矩形[1]);
	}
	
	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_数量;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}



uint16 f_vg_画连接点(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元) {
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	return s->m_绘制推进层;
}

uint16 f_vg_画圆形(S_2D画布* s, S_2D笔刷& 笔刷, float32 半径, bool 是否填充, bool 是否开始新图元) {
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);
	return s->m_绘制推进层;
}

uint16 f_vg_画单色图标(S_2D画布* s, uint16 属性, std::string 图标集) {
	f_vg_记录图元(s, s->m_调色板->m_单色图标笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8*));
		f_alloc_笔刷槽数量(e, 3);
		

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = s->g图标变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = s->g图标颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		//m_纹理库对象
		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		e.m_纹理信息[0] = s->m_调色板->m_ICOs[图标集].m_Tex;
		//e.m_纹理库对象 = 图标集;

		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;

		s->m_surf[s->m_绘制推进层].m_纹理 = 图标集;
		s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	}

	return s->m_绘制推进层;
}

uint16 f_vg_画图标(S_2D画布* s, uint16 属性, std::string 图标集) {
	f_vg_记录图元(s, s->m_调色板->m_纯纹理图标笔刷);
	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
	{
		//e.m_参数元素数量 = 3;
		//e.m_参数槽 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
		//e.m_绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
		f_alloc_笔刷槽数量(e, 3);
		

		if (s->m_父级画布属性) e.m_参数槽[0] = s->m_父级画布属性;
		else e.m_参数槽[0] = s->m_属性[属性];
		e.m_绑定位置[0] = DEF_BINDING_WIDGET_PROP;

		e.m_参数槽[1] = s->g图标变换;
		e.m_绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;

		e.m_参数槽[2] = s->g图标颜色;
		e.m_绑定位置[2] = DEF_BINDING_WIDGET_Color;

		//m_纹理库对象
		e.m_纹理信息 = (S_纹理**)calloc(1, sizeof(S_纹理*));
		e.m_纹理信息[0] = s->m_调色板->m_ICOs[图标集].m_Tex;
		//e.m_纹理库对象 = 图标集;

		if (e.m_纹理信息[0]) {
			e.m_纹理参数数量 = 1;
		}
		else e.m_纹理参数数量 = 0;

		s->m_surf[s->m_绘制推进层].m_纹理 = 图标集;
		s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	}

	return s->m_绘制推进层;
}

uint16 f_vg_画文本(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	//if (是否开始新图元) f_vg_记录图元(s, 笔刷.m_材质);

	//s->m_surf[s->m_绘制推进层].m_纹理 = 笔刷.m_纹理库对象;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	//s->m_surf[s->m_绘制推进层].m_着色参数 = 笔刷.m_GPU参数set;
	//s->m_surf[s->m_绘制推进层].m_Material = 笔刷.m_材质;
	return s->m_绘制推进层;
}

uint16 f_vg_画3D视口(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元) {
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.g_材质);
	//if (是否开始新图元) f_vg_记录图元(s);

	//s->m_surf[s->m_绘制推进层].m_纹理 = 笔刷.m_纹理库对象;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
	//s->m_surf[s->m_绘制推进层].m_着色参数 = 笔刷.m_GPU参数set;
	//s->m_surf[s->m_绘制推进层].m_Material = 笔刷.m_材质;
	return s->m_绘制推进层;
}

uint16 f_vg_画纹理面(S_2D画布* s, S_2D笔刷& 笔刷) {
	if (true) f_vg_记录图元(s, 笔刷.g_材质);
	//if (true) f_vg_记录图元(s);
	//s->m_surf[s->m_绘制推进层].m_着色参数 = 笔刷.m_GPU参数set;
	//s->m_surf[s->m_绘制推进层].m_Material = 笔刷.m_材质;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = 4;
	return s->m_绘制推进层;
}



void f_vg_set绘制线(S_2D画布* s, uint16 eID, uint32 offset, const vec2& point) {
	assert(eID < s->m_surf.size());
	S_2D图元顶点 lp = { point , {0,0}, {0,0} };
	if (s->m_surf[eID].m_顶点.m_Mem.m_数量 <= offset) {
		f_bm_resize(s->m_surf[eID].m_顶点, s->m_surf[eID].m_顶点.m_Mem.m_数量 + 1);
	}
	auto* v = f_buf_图元顶点_ptr(s->m_surf[eID].m_顶点);
	v[offset] = lp;
}

void f_vg_set绘制线(S_2D画布* s, uint16 eID, uint32 num) {
	f_bm_resize(s->m_surf[eID].m_顶点, num);
}





void f_vg_set顶点数量(S_2D画布* s, uint16 eID, int32 num) {
	s->m_surf[eID].m_顶点数量 = num;
}

void f_vg_set实例数量(S_2D画布* s, uint16 eID, int32 num) {
	s->m_surf[eID].m_实例数量 = num;
}

void f_vg_set属性(S_2D画布* s, uint16 eID, vec2 缩放, vec2 位置偏移, int32 梯度, int32 图标间隔) {
	S_2D_PanelAttr prop;
	prop.m_Scale = 缩放;
	prop.m_Offset = 位置偏移;
	prop.m_渐变数量 = 梯度;
	prop.m_间隔 = 图标间隔;
	//if (s->m_父级画布属性) e.m_参数元素[0] = s->m_父级画布属性;
	//else e.m_参数元素[0] = s->m_属性[属性];
	f_buf_set(s->m_属性[eID], 0, prop);
}

void f_vg_set渐变梯度(S_2D画布* s, uint16 eID, vec2 dir) {
}


//void f_vg_add变换实例(S_2D画布* s, uint16 eID, uint32 nums) {
//	assert(eID < s->m_扩展GPU参数.size());
//	std::vector<mat3X2> v(nums);
//	f_buf_push_back<mat3X2>(s->m_扩展GPU参数[eID], v);
//	
//}

//void f_vg_add单色实例(S_2D画布* s, uint16 eID, uint32 nums) {
//	assert(eID < s->m_扩展GPU参数.size());
//	std::vector<uint32> v(nums);
//	f_buf_push_back<uint32>(s->m_扩展GPU参数[eID], v);
//}

//void f_vg_add遮罩实例(S_2D画布* s, uint16 eID, uint32 nums) {
//	assert(eID < s->m_扩展GPU参数.size());
//	std::vector<uint8> v(nums);
//	f_buf_push_back<uint8>(s->m_扩展GPU参数[eID], v);
//}





void f_vg_set属性(S_2D画布* s, uint16 eID, const S_2D_PanelAttr& 属性) {
	assert(eID < s->m_属性.size());
	f_buf_set(s->m_属性[eID], 0, 属性);
	//if (s->m_父级画布属性) e.m_参数元素[0] = s->m_父级画布属性;
	//else e.m_参数元素[0] = s->m_属性[属性];
}

void f_vg_set变换(S_2D画布* s, uint16 eID, uint32 offset, const mat3X2& mat) {
	assert(eID < s->m_扩展GPU参数.size());
	f_buf_set(s->m_扩展GPU参数[eID], offset, mat);
}

void f_vg_set单色(S_2D画布* s, uint16 eID, uint32 offset, const S_RGBA8UI color) {
	assert(eID < s->m_扩展GPU参数.size());
	f_buf_set(s->m_扩展GPU参数[eID], offset, f_PackData4X8(color));
}

void f_vg_setUV(S_2D画布* s, uint16 eID, uint16 icoID, uint32 offset, std::string iconame) {
	float32 uv = s->m_调色板->m_ICOs[s->m_surf[eID].m_纹理][iconame];
	f_buf_set(s->m_扩展GPU参数[icoID], offset, uv);
}

void f_vg_set颜色2(S_2D画布* s, uint16 eID, uint32 offset, const S_RGBA8UI colorA, const S_RGBA8UI colorB) {
	uvec2 color;
	color.x = f_PackData4X8(colorA);
	color.y = f_PackData4X8(colorB);

	f_buf_set(s->m_扩展GPU参数[eID], offset, color);
}

void f_vg_set纹理(S_2D笔刷* b, uint16 eID, S_纹理* text) {
	if (!text) {
		std::cout<<text<<std::endl;
	}
		
	b->m_纹理信息[eID] = text;
	b->m_纹理参数数量 = 1;
}

void f_vg_set纹理(S_2D画布* s, uint16 元素, uint16 eID, S_纹理* text) {
	s->m_surf[元素].m_笔刷.m_纹理信息[eID] = text;
	s->m_surf[元素].m_笔刷.m_纹理参数数量 = 1;
}

//void f_vg_set间接绘制参数(S_2D画布* s, uint16 元素, uvec2 顶点偏移数量, uint32 变换偏移, uint32 实例数量) {
//	S_VkDrawIndirectCommand ic = { 顶点偏移数量.y ,实例数量, 顶点偏移数量.x, 变换偏移 };
//	if(s->m_surf[元素].m_间接.m_Mem.m_大小 == 0) f_buf_gresize(s->m_surf[元素].m_间接, 1);
//	f_buf_Indirect_ptr(s->m_surf[元素].m_间接)[0] = ic;
//}

void f_vg_set图元(S_2D画布* s, uint16 元素, uint32 偏移, uvec2 图元) {
	f_buf_set(s->m_扩展GPU参数[元素], 偏移, 图元);
}

void f_vg_set单色(S_凸边图元& 图元, uint32 offset, const S_RGBA8UI color) {
	f_buf_UI32_at(*图元.颜色, offset) = f_PackData4X8(color);
	//f_buf_set(图元.颜色, offset, f_PackData4X8(color));
}








void f_vg_set纹理(S_2D笔刷& 笔刷, uint32 offset, S_纹理* 纹理) {
	if (!纹理) {
		std::cout << "f_vg_set纹理 : " << 纹理 << std::endl;
	}
	
	笔刷.m_纹理信息[offset] = 纹理;
	笔刷.m_纹理参数数量 = 1;
}

S_板载缓存* f_vg_get属性(S_2D画布* s, uint16 ID) {
	return s->m_属性[ID];
}




std::wstring f_vg_set行文本(S_2D画布* s, uint32 纹理集, std::wstring text, uint32 偏移, float32 width, int32* text_ptr) {
	uint32 num = text.size();
	if (!num) {
		return L"";
	}
	

	auto& 文字tex = s->m_调色板->m_Fonts[s->m_surf[纹理集].m_纹理];
	//width -= 文字tex.f_get字符宽度('.')*2;
	std::wstring new_text;

	float32 w = 0;
	uint32 i = 0;
	uint8	是否省略 = 0;
	for( ; i < num; ++i) {
		w += 文字tex.f_get字符宽度(text[i]);

		if (w > width) {
			new_text += L'*';
			text_ptr[偏移 + i] = L'*';

			//是否省略 = true;
			//break;
			if(是否省略 >= 3) break;
			++是否省略;
		}
		else {
			new_text += text[i];
			text_ptr[偏移 + i] = text[i];
		}

		w += S_UI主题::ui_文字间隔;
		//text_ptr[偏移 + i] = 文字tex.f_从外部编码取内部编码(text[i]);
	}
	
	//if (是否省略 && i > 3) {
	//	i -= 3;
	//	num = L'.';
	//	text_ptr[偏移 + i] = num;
	//	text_ptr[偏移 + ++i] = num;
	//	text_ptr[偏移 + ++i] = num;
	//}

	return new_text;
}

void f_vg_del文本段(S_2D画布* s, const S_2D文本对象& eID, uint32 offset, uint32 区偏移) {
	
	s->m_扩展GPU参数[eID.文本ID]->f_map();
	f_板载缓存_remove段_swapEnd<int32>(s->m_扩展GPU参数[eID.文本ID], offset * eID.区间大小, eID.区间大小);
	s->m_扩展GPU参数[eID.文本ID]->f_unmap();
}

void f_vg_resize行文本(S_2D画布* s, const S_2D文本对象& eID, uint32 num, bool 冗余)
{
	f_buf_resize(s->m_扩展GPU参数[eID.文本ID], num);
}













void f_vg_set属性间隔成员(S_2D画布* s, uint16 eID, float32 v) {
	s->m_属性[eID]->f_map();
	((S_2D_PanelAttr*)s->m_属性[eID]->m_mappedPtr)->m_间隔 = v;
	s->m_属性[eID]->f_unmap();
}



void f_vg_关联凸边形颜色属性(const S_2D画布* s, S_2D画布* s2, uint16 层) {
	if (s2->m_surf.size() > 层) {
		s2->m_surf[层].m_笔刷.m_参数槽[2] = s->m_surf[层].m_笔刷.m_参数槽[2];
	}
}




bool f_vg_增量添加图标(S_2D画布* s, uint16 元素ID, uint16 UVID, uint32 offset, std::string iconame) {
	//需要改进处------------!!!!!!!!!!!!!!!!!!!!!!!!!!!! 可替换成支持多线程

	float32 uv = s->m_调色板->m_ICOs[s->m_surf[元素ID].m_纹理][iconame];
	//std::cout << "uv==" << uv << std::endl;
	bool 更新GPU端 = f_resize板载缓存_Up(s->m_扩展GPU参数[UVID], offset + 1);
	f_buf_set(s->m_扩展GPU参数[UVID], offset, uv);

	return 更新GPU端;
}

void f_vg_set图标(S_2D画布* s, uint32* icoUV, uint16 元素ID, uint16 UVID, uint32 offset, std::string iconame) {
	icoUV[offset] = s->m_调色板->m_ICOs[s->m_surf[元素ID].m_纹理][iconame];
}







void f_vg_tranform(S_2D画布* s, vec2 loc, vec2 scal, vec2 rot) {
	mat3 mat = f_mat3x3_Identity();
	
	mat *= f_mat3x3_Location(loc);
	mat *= f_mat3x3_Scale(scal);

	f_bm_Mat3_at(s->m_变换) = mat;
}

void f_vg_setLineWidth(S_2D画布* s, uint32 元素, float32 w) {
	auto& 层 = *s->m_绘制元素[元素];
	层.m_线宽 = w;
}

void f_vg_tranform(S_Surface2D& surf, vec2 loc, vec2 scal, vec2 rot, uint32 offset) {
	mat3 mat = f_mat3x3_Identity();

	mat *= f_mat3x3_Location(loc);
	mat *= f_mat3x3_Scale(scal);

	f_bm_at<mat3>(surf.m_元素变换, offset) = mat;
}

void f_vg_tranform(S_Surface2D& surf, uint32 num, vec2* loc, vec2* scal) {
	f_bm_resize(surf.m_元素变换, max(num, 1));
	if (num) {
		auto ptr = f_bm_ptr<mat3>(surf.m_元素变换);
		for(uint32 i = 0; i < num; ++i) {
			ptr[i] = f_mat3x3_Location(loc[i]);
			ptr[i] *= f_mat3x3_Scale(scal[i]);
		}
	}
}

void f_vg_tranform(S_Surface2D& surf, uint32 num, vec2* loc) {
	f_bm_resize(surf.m_元素变换, num + 1);
	if (num) {
		auto ptr = f_bm_ptr<mat3>(surf.m_元素变换);
		for(uint32 i=0; i<num; ++i) ptr[i] = f_mat3x3_Location(loc[i]);
	}
}

void f_vg_color(S_Surface2D& surf, uint32 num, S_RGBA8UI* color) {
	if (num) {
		f_bm_resize(surf.m_元素颜色, num);
		auto ptr = f_bm_ptr<uvec2>(surf.m_元素颜色);
		for (uint32 i = 0; i < num; ++i) {
			ptr[i] = S_2D颜色包(color[i], 0, 0, 0);
		}
	}
	else {
		f_bm_resize(surf.m_元素颜色, 1);
		f_bm_at<uvec2>(surf.m_元素颜色) = {};
	}
}

void f_vg_color(S_Surface2D& surf, uint32 num, S_2D颜色包* color) {
	if (num) {
		f_bm_resize(surf.m_元素颜色, num);
		auto ptr = f_bm_ptr<uvec2>(surf.m_元素颜色);
		for (uint32 i = 0; i < num; ++i) {
			ptr[i] = color[i];
		}
	}
	else {
		f_bm_resize(surf.m_元素颜色, 1);
		f_bm_at<uvec2>(surf.m_元素颜色) = {};
	}
}



//======================================== 线 ===================================================

static void f_Line_着色器参数配置(S_设备环境& ctx, S_Surface2D& surf) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	auto& push = f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送);
	push.m_Offset_TranformL = surf.m_元素变换.m_Mem.m_偏移;
	push.m_Offset_Color = surf.m_元素颜色.m_Mem.m_偏移;
}

S_Surface2D* f_vg_genLine(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_线类型 线类型) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.push_back(surf);

	surf->mf_参数设置回调 = f_Line_着色器参数配置;
	surf->m_画布变换 = &画布.m_变换;
	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_序列元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_线[混合模式];

	if (线类型 == E_线类型::e_线段) {
		surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_间接;
	}
	else {
		surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_序列;
		surf->m_平面形状 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	}
	
	f_df_创建常量推送<S_ConstPush_2DPolygonElement>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	auto& push = f_df_推送常量<S_ConstPush_2DPolygonElement>(surf->m_常量推送);
	push.m_Offset_TranformG = 画布.m_变换.m_Mem.m_偏移;
	push.m_Offset_TranformL = surf->m_元素变换.m_Mem.m_偏移;
	return surf;
}
void f_vg_setLine(S_2D画布* s, uint32 线, uint32 num, vec2* point, S_RGBA8UI* color) {
	f_bm_resize(s->m_绘制元素[线]->m_顶点, num);
	if (num) {
		auto* p = f_bm_2D线_ptr(s->m_绘制元素[线]->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			p[i].point = point[i];
			p[i].uv_width = {0,0};
			p[i].AA_type = {f_PackData4X8(color[i]), 0};
		}
	}
}
void f_vg_setLine(S_2D画布* s, uint32 线, uint32 num, vec2* point, S_RGBA8UI color) {
	auto& 层 = *s->m_绘制元素[线];

	f_bm_resize(层.m_顶点, num);
	if (num) {
		auto* p = f_bm_2D线_ptr(层.m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			p[i].point = point[i];
			p[i].uv_width = point[i];
			p[i].AA_type = { f_PackData4X8(color), 0 };
		}
	}
	
	auto& indirect = f_buf_Indirect_at(层.m_间接);
	indirect.firstInstance = 0;
	indirect.instanceCount = s->m_变换.m_Mem.m_数量;
	indirect.firstVertex = 层.m_顶点.m_Mem.m_偏移;
	indirect.vertexCount = 层.m_顶点.m_Mem.m_数量;
}

void f_vg_setLine(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[], float32 线宽) {
	if (num) {
		f_bm_resize(层.m_间接, num);

		auto* indirect = f_buf_Indirect_ptr(层.m_间接);
		for (uint32 i = 0; i < num; ++i) {
			indirect[i].firstInstance = 0;
			indirect[i].instanceCount = 1;
			indirect[i].firstVertex = 块元素[i]->m_Mem.m_偏移;
			indirect[i].vertexCount = 块元素[i]->m_Mem.m_数量;
		}
	}
	else {
		f_bm_resize(层.m_间接, 1);
		f_buf_Indirect_at(层.m_间接) = {};
	}
	层.m_线宽 = 线宽;
}

void f_vg_setLine(S_Surface2D& 层, uint32 num, vec2* 线坐标, float32 线宽) {
	auto& point = 层.m_平面形状;
	f_bm_resize(point, num);
	if (num) {
		auto* ptr = f_bm_ptr<mat2>(point);

		for (uint32 i = 0; i < num; ++i) {
			ptr[i] ={线坐标[i], {1,1}};
		}
	}
	层.m_线宽 = 线宽;
}




//======================================== 图标 ===================================================

struct S_图标GPU参数 {
	S_TexArrayRes* m_图标纹理坐标;
};

static void f_ICO_着色器参数配置(S_2D画布* 画布, S_Surface2D* surf, S_板载缓存* 视图矩阵) {
	S_图标GPU参数& 参数 = *((S_图标GPU参数*)surf->m_自定义属性参数);

	surf->m_多维材质槽.m_参数槽.m_参数槽[0] = 视图矩阵;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[0] = DEF_BINDING_PROJECT;
	surf->m_多维材质槽.m_参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[0] = 1;
}
static void f_ICO_销毁自定义参数(S_Surface2D* surf) {
	S_图标GPU参数& 参数 = *((S_图标GPU参数*)surf->m_自定义属性参数);
	f_releaseGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽);
}

uint32 f_vg_get图标UV(S_2D画布* s, uint32 图标, const std::string name) {
	auto& 层 = *s->m_绘制元素[图标];
	auto& icoUV = ((S_图标GPU参数*)层.m_自定义属性参数)->m_图标纹理坐标->m_Name;

	uint32 uv = 0;
	if (icoUV.find(name) != icoUV.end()) {
		uv = icoUV[name];
	}
	return uv;
}

S_2D图标 f_vg_2D图标(const vec2& 坐标, uint32 图标UV, const S_RGBA8UI& 颜色, float32 大小, uint32 着色类型) {
	S_2D图标 ico;
	ico.point = 坐标;
	ico.ICO_Size.x = 图标UV;
	ico.ICO_Size.y = 大小;
	ico.AA_type.x = f_PackData4X8(颜色);
	ico.AA_type.y = 着色类型;
	return ico;
}

uint32 f_vg_drawIco(S_2D画布* s, std::string 图标集) {
	S_Surface2D* surf = f_surface2D_alloc(s->m_Ctx);

	surf->m_顶点 = f_bm_alloc(f_buf_getGlobal().m_2D线, 0);
	surf->m_多维材质槽.m_Material = s->m_调色板->m_图标;
	surf->mf_绘制参数设置 = f_ICO_着色器参数配置;
	surf->mf_销毁自定义参数 = f_ICO_销毁自定义参数;


	S_图标GPU参数* 参数 = (S_图标GPU参数*)malloc(sizeof(S_图标GPU参数));
	参数->m_图标纹理坐标 = &(s->m_调色板->m_ICOs[图标集]);

	surf->m_纹理槽 = f_纹理槽_创建(1);
	f_纹理槽_设置纹理(surf->m_纹理槽, 参数->m_图标纹理坐标->m_Tex, DEF_BINDING_WIDGET_Texture, 0);


	f_df_allocGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽, 2);
	surf->m_多维材质槽.m_参数槽.m_参数槽[1] = &s->m_变换;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[1] = 1;
	surf->m_多维材质槽.m_参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[1] = 1;


	surf->m_多维材质槽.m_参数槽.m_纹理槽 = &(surf->m_纹理槽);

	f_df_创建常量推送<S_2DICO_PanelAttr>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	auto& push = f_df_推送常量<S_2DICO_PanelAttr>(surf->m_常量推送);
	push.m_Offset_Instance = s->m_变换.m_Mem.m_偏移;

	surf->m_自定义属性参数 = 参数;
	surf->m_实例数量 = s->m_变换.m_Mem.m_数量;
	surf->m_实例偏移 = s->m_变换.m_Mem.m_偏移;
	surf->m_线宽 = 1;

	uint32 图标 = s->m_绘制元素.size();
	s->m_绘制元素.push_back(surf);
	return 图标;
}

void f_vg_setIco(S_2D画布* s, uint32 图标, uint32 num, S_2D图标* ico) {
	auto& 层 = *s->m_绘制元素[图标];
	f_bm_resize(层.m_顶点, num);

	if (ico && num) {
		f_gbuf_fill(s->m_绘制元素[图标]->m_顶点, ico, 0, num);
	}

	S_图标GPU参数& ico参数 = *((S_图标GPU参数*)层.m_自定义属性参数);
	f_纹理槽_设置纹理(层.m_纹理槽, ico参数.m_图标纹理坐标->m_Tex, DEF_BINDING_WIDGET_Texture, 0);
}

void f_vg_setIco(S_2D画布* s, uint32 图标, uint32 index, vec2 point, S_RGBA8UI color, std::string name, float32 size, uint32 绘制方式) {
	auto& 层 = *s->m_绘制元素[图标];
	auto& icoUV = ((S_图标GPU参数*)层.m_自定义属性参数)->m_图标纹理坐标->m_Name;

	uint32 uv = 0;
	if (icoUV.find(name) != icoUV.end()) {
		uv = icoUV[name];
	}

	f_bm_at<S_2D图标>(层.m_顶点, index) = { point, { uv, uint32(size) }, { f_PackData4X8(color), 绘制方式} };
}

//void f_vg_ico_tranform(S_2D画布* s, uint32 元素, vec2 loc, vec2 scal, vec2 rot) {
//	mat3 mat = f_mat3x3_Identity();
//	mat *= f_mat3x3_Location(loc);
//}

S_Surface2D* f_vg_genIco(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式, std::string 图标集) {
	auto* rf = f_vk_get绘图框架(ctx);
	S_Surface2D* surf = f_vg_genPolygon(ctx, 画布, 混合模式, 填充模式);
	return surf;
}

void f_vg_drawIco(S_Surface2D& 层, uint32 num, const std::u16string 图标[]) {
	if (num) {
		f_bm_resize(层.m_间接, num);
		auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(层.m_间接);

		for (uint32 i = 0; i < num; ++i) {
			indirect[i] = f_vg_getIco(图标[i], 层.m_填充面);
		}
	}
	else {
		f_bm_resize(层.m_间接, 1);
		f_buf_Indirect_at(层.m_间接) = {};
	}
}






//======================================== 文字 ===================================================
struct S_字符GPU参数 {
	S_GPU内存块 字符;
	S_GPU内存块 字符纹理坐标;
	const S_Font* 字体;
	float32 字体大小;
};

//static void f_Char_着色器参数配置(S_2D画布* 画布, S_Surface2D* surf, S_板载缓存* 视图矩阵) {
//	S_字符GPU参数& 参数 = *((S_字符GPU参数*)surf->m_自定义属性参数);
//	S_2DChar_PanelAttr& attr = *(S_2DChar_PanelAttr*)surf->m_常量推送;
//
//	surf->m_多维材质槽.m_参数槽.m_参数槽[0] = 视图矩阵;
//	surf->m_多维材质槽.m_参数槽.m_绑定位置[0] = DEF_BINDING_PROJECT;
//	surf->m_多维材质槽.m_参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
//	surf->m_多维材质槽.m_参数槽.m_绑定数量[0] = 1;
//
//	attr.m_Offet_Char = 参数.字符.m_Mem.m_偏移;
//	attr.m_Offet_CharUV = 参数.字符纹理坐标.m_Mem.m_偏移;
//	attr.m_AlignType = 0;
//}
//static void f_Char_销毁自定义参数(S_Surface2D* surf) {
//	S_字符GPU参数& 参数 = *((S_字符GPU参数*)surf->m_自定义属性参数);
//	f_bm_erase(参数.字符);
//	f_releaseGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽);
//}

//S_Surface2D* f_vg_genLineText(S_设备环境& ctx, std::u16string 字体, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式) {
//	auto* rf = f_vk_get绘图框架(ctx);
//	auto* rt = f_vk_get绘图环境(ctx);
//
//	S_Surface2D* surf = f_vg_drawPolygon(ctx, 画布, 混合模式, 填充模式);
//	surf->m_字体 = &rf->m_字体[字体];
//
//	return surf;
//}
//
//void f_vg_lineText_begin(S_2D画布* s, uint32 行文本) {
//	auto& 层 = *s->m_绘制元素[行文本];
//	S_字符GPU参数& 参数 = *(S_字符GPU参数*)层.m_自定义属性参数;
//
//	f_bm_erase(参数.字符);
//	f_bm_erase(层.m_顶点);
//}
//
//void f_vg_setLineText(S_2D画布* s, uint32 行文本, std::wstring text, const S_Rect2Df rect, E_对齐方式 对齐方式, S_RGBA8UI color, E_方向 方向) {
//	auto& 层 = *s->m_绘制元素[行文本];
//	S_字符GPU参数& 参数 = *(S_字符GPU参数*)层.m_自定义属性参数;
//
//	
//	std::vector<int32> t;
//	float32 宽度 = 0;
//	for(auto& e : text) {
//		宽度 += 参数.字体->f_get字符宽度(e) + 2;
//		if (宽度 > rect.extent.x) {
//			t.push_back('*');
//			break;
//		}
//		else {
//			t.push_back(e);
//		}
//	}
//
//	S_2D字符 字符点;
//	字符点.point = rect.offset;
//	字符点.CharOffset_Num.x = 参数.字符.m_Mem.m_数量;
//	字符点.CharOffset_Num.y = t.size();
//	字符点.color_type.x = f_PackData4X8(color);
//	字符点.color_type.y = 0;
//
//
//	switch (方向) {
//		case E_方向::e_横向: {
//			switch (对齐方式) {
//				case E_对齐方式::e_左对齐: {
//					break;
//				}
//				case E_对齐方式::e_右对齐: {
//					字符点.point.x += rect.extent.x - 宽度;
//					break;
//				}
//				case E_对齐方式::e_据中对齐: {
//					//字符点.point.x += rect.extent.x - 宽度;
//					字符点.point.x += (rect.extent.x - 宽度) * 0.5;
//					字符点.point.y += (rect.extent.y - (参数.字体->m_字号 + 4)) * 0.5;
//					break;
//				}
//				default:
//					break;
//			}
//			break;
//		}
//		case E_方向::e_纵向: {
//			
//			break;
//		}
//		default:
//			break;
//	}
//	
//
//	f_bm_push_back(层.m_顶点, &字符点, 1);
//	f_buf_push_back(参数.字符, t);
//}



struct S_多边形绘制GPU参数 {
	S_GPU内存块 字符;
	S_GPU内存块 字符纹理坐标;
	const S_Font* 字体;
};

//static void f_String_着色器参数配置(S_2D画布* 画布, S_Surface2D* surf, S_板载缓存* 视图矩阵) {
//	S_字符GPU参数& 参数 = *((S_字符GPU参数*)surf->m_自定义属性参数);
//	S_ConstPush_2DPolygonElement& attr = *(S_ConstPush_2DPolygonElement*)surf->m_常量推送;
//
//	surf->m_多维材质槽.m_参数槽.m_参数槽[0] = 视图矩阵;
//	surf->m_多维材质槽.m_参数槽.m_绑定位置[0] = DEF_BINDING_PROJECT;
//	surf->m_多维材质槽.m_参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
//	surf->m_多维材质槽.m_参数槽.m_绑定数量[0] = 1;
//
//}
//static void f_String_销毁自定义参数(S_Surface2D* surf) {
//	S_字符GPU参数& 参数 = *((S_字符GPU参数*)surf->m_自定义属性参数);
//	f_bm_erase(参数.字符);
//	f_releaseGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽);
//}





static void f_drawPolygon_参数设置(S_设备环境& ctx, S_Surface2D& surf) {
	auto* rt = f_vk_get绘图环境(ctx);
	auto* rf = f_vk_get绘图框架(ctx);

	auto& push = f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送);

	push.m_Offset_TranformG = uint32(surf.m_画布变换->m_Mem.m_偏移);
	push.m_Offset_TranformL = uint32(surf.m_元素变换.m_Mem.m_偏移);
	push.m_Offset_Color = uint32(surf.m_元素颜色.m_Mem.m_偏移);

}
S_Surface2D* f_vg_genPolygon(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式) {
	auto* rt = f_vk_get绘图环境(ctx);

	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);

	surf->m_画布变换 = &画布.m_变换;
	surf->mf_参数设置回调 = f_drawPolygon_参数设置;
	if (填充模式 == E_填充模式::e_填充面) {
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_多边形[混合模式];
	}
	else if (填充模式 == E_填充模式::e_填充线) {
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_线[混合模式];
		surf->m_填充面 = false;
	}

	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_索引元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_间接索引;
	
	f_df_创建常量推送<S_ConstPush_2DPolygonElement>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	
	auto& push = f_df_推送常量<S_ConstPush_2DPolygonElement>(surf->m_常量推送);
	push.m_Offset_TranformG = uint32(surf->m_画布变换->m_Mem.m_偏移);
	return surf;
}

static auto 多边形绘制分配内存 = [](S_Surface2D& surf, uint32 num) {
	f_bm_resize(surf.m_间接, num);
	f_bm_resize(surf.m_元素变换, num);
	f_bm_resize(surf.m_元素颜色, num);
	//f_buf_Indirect_at(surf.m_间接) = {};
};

static auto 多边形常量推送初始化 = [](S_Surface2D& 层, S_ConstPush_2DPolygonElement* const_push) {
	const_push->m_Offset_TranformL = 层.m_元素变换.m_Mem.m_偏移;
	const_push->m_Offset_Color = 层.m_元素颜色.m_Mem.m_偏移;
};

static auto 字符串绘制设置字符 = [](S_Surface2D& surf, uint32 offset, const std::u16string text, const uvec2* 纹理索引区间, const S_Rect2Df& rect, const S_RGBA8UI& 颜色) {
	auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(surf.m_间接);
	auto* tranform = f_bm_ptr<mat3>(surf.m_元素变换);
	auto* color = f_bm_ptr<uvec2>(surf.m_元素颜色);

	uint32 num = text.size();
	for (uint32 i = 0; i < num; ++i) {
		int32 t = int32(text[i]);
		auto r = 纹理索引区间[t];

		indirect[i].firstInstance = 0;
		indirect[i].instanceCount = 1;

		indirect[i].firstIndex = r.x;
		indirect[i].indexCount = r.y;

		indirect[i].vertexOffset = 0;

		auto m = f_math_tranform({100.0f * (i), 100}, rect.extent);
		tranform[i] = m;
		color[i] = S_2D颜色包(颜色, 0, 0, 0);
	}
};

S_Surface2D* f_vg_genString(S_设备环境& ctx, S_2D画布& 画布, E_填充模式 填充模式, E_图层混合模式 混合模式, std::u16string 字体) {
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);

	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);

	surf->m_画布变换 = &画布.m_变换;
	surf->mf_参数设置回调 = f_drawPolygon_参数设置;
	if (填充模式 == E_填充模式::e_填充面) {
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_文字[混合模式];
	}
	else if (填充模式 == E_填充模式::e_填充线) {
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_线[混合模式];
		surf->m_填充面 = false;
	}

	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_索引元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_间接索引;

	f_df_创建常量推送<S_ConstPush_2DPolygonElement>(surf->m_常量推送, E_着色阶段::e_顶点着色);

	auto& push = f_df_推送常量<S_ConstPush_2DPolygonElement>(surf->m_常量推送);
	push.m_Offset_TranformG = uint32(surf->m_画布变换->m_Mem.m_偏移);
	//return surf;
	//S_Surface2D* surf = f_vg_genPolygon(ctx, 画布, 混合模式, 填充模式);
	surf->m_字体 = &rf->m_字体[字体];
	return surf;
}

void f_vg_drawString(S_Surface2D& surf, std::u16string text, S_Rect2Df rect, S_RGBA8UI 颜色, E_对齐方式 对齐方式, S_行字符串绘制属性 属性) {
	float32 h = rect.extent.y;
	vec2 pos = f_vg_lineStringCutOut(*surf.m_字体, text, rect, 对齐方式, h, 属性.m_间距);

	uint32 num = text.size();
	if (num) {
		
		f_bm_resize(surf.m_间接, num);
		f_bm_resize(surf.m_元素变换, num);
		f_bm_resize(surf.m_元素颜色, num);
		
		auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(surf.m_间接);
		auto* tranform = f_bm_ptr<mat3>(surf.m_元素变换);
		auto* color = f_bm_ptr<uvec2>(surf.m_元素颜色);
		

		auto 设置字符 = [&](const uvec2* 纹理索引区间) {
			pos.y = rect.offset.y + rect.extent.y * 0.15;

			for (uint32 i = 0; i < num; ++i) {
				int32 t = int32(text[i]);
				auto r = surf.m_字体->m_矢量文字索引区间[t];

				indirect[i].firstInstance = 0;
				indirect[i].instanceCount = 1;

				indirect[i].firstIndex = r.x;
				indirect[i].indexCount = r.y;

				indirect[i].vertexOffset = 0;
				
				tranform[i] = f_math_tranform(pos, { h, h });
				color[i] = S_2D颜色包(颜色, 0, 0, 0);

				pos.x += ( surf.m_字体->m_字符属性[t].horiBearingX ) * h + 属性.m_间距;
			}
		};
		if (surf.m_填充面) {
			设置字符(surf.m_字体->m_矢量文字索引区间.data());
		}
		else {
			设置字符(surf.m_字体->m_矢量文字边索引区间.data());
		}
	}
	else {
		f_bm_resize(surf.m_间接, 0);
		f_bm_resize(surf.m_元素变换, 0);
		f_bm_resize(surf.m_元素颜色, 0);
		//f_buf_Indirect_at(surf.m_间接) = {};
	}

	//((S_ConstPush_2DPolygonElement*)(surf.m_常量推送))->m_Offset_TranformL = surf.m_元素变换.m_Mem.m_偏移;
	//((S_ConstPush_2DPolygonElement*)(surf.m_常量推送))->m_Offset_Color = surf.m_元素颜色.m_Mem.m_偏移;
	多边形常量推送初始化(surf, &f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送));
	
}

void f_vg_drawString(S_Surface2D& surf, 
					std::vector<std::u16string> text, 
					const std::vector<S_Rect2Df>& rects, 
					const std::vector<S_RGBA8UI>& color, 
					E_对齐方式 对齐方式,
					S_行字符串绘制属性 属性 ) {
	
	uint32 num = text.size();
	
	std::vector<float32> widths(num);

	uint32 分配数量 = 0;
	for (uint32 i = 0; i < num; ++i) {
		widths[i] = f_vg_StringCutOut(*surf.m_字体, text[i], rects[i].extent.x, rects[i].extent.y, 属性.m_间距);
		分配数量 += text[i].size();
	}

	if (num && 分配数量) {
		多边形绘制分配内存(surf, 分配数量);
	
		auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(surf.m_间接);
		auto* tranform = f_bm_ptr<mat3>(surf.m_元素变换);
		auto* color_ptr = f_bm_ptr<uvec2>(surf.m_元素颜色);
		uint32 offset = 0;

		auto 设置字符 = [&](std::u16string& str, const uvec2* 纹理索引区间, S_Rect2Df rect, float32 width, const S_RGBA8UI& 颜色) {
			float32 h = rect.extent.y;
			vec2 pos = f_vg_lineStringDrawPos(rect, width, 对齐方式);
			
			float32 推进 = 0;

			uint32 字符数量 = str.size();
			if (字符数量) {
				for (uint32 i = 0; i < 字符数量; ++i) {
					int32 t = int32(str[i]);
					auto r = surf.m_字体->m_矢量文字索引区间[t];

					uint32 index = i + offset;
					indirect[index].firstInstance = 0;
					indirect[index].instanceCount = 1;

					indirect[index].firstIndex = r.x;
					indirect[index].indexCount = r.y;

					indirect[index].vertexOffset = 0;


					tranform[index] = f_math_tranform(pos, {h, h});
					pos.x += ( surf.m_字体->m_字符属性[t].horiBearingX ) * h + 属性.m_间距;

					color_ptr[index] = S_2D颜色包(颜色, 0, 0, 0);
				}
				offset += 字符数量;
			}
			
		};


		if (surf.m_填充面) {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字索引区间.data(), rects[i], widths[i], color[i]);
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字边索引区间.data(), rects[i], widths[i], color[i]);
			}
		}
	}
	else {
		多边形绘制分配内存(surf, 0);
	}
	多边形常量推送初始化(surf, &f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送));
}

void f_vg_drawString(S_Surface2D& surf, 
					std::vector<std::u16string> text, 
					const std::vector<S_Rect2Df>& rects, 
					const std::vector<S_RGBA8UI>& color, 
					const std::vector<E_对齐方式>& 对齐方式, 
					S_行字符串绘制属性 属性)
{
	uint32 num = text.size();
	std::vector<float32> widths(num);

	uint32 分配数量 = 0;
	for (uint32 i = 0; i < num; ++i) {
		widths[i] = f_vg_StringCutOut(*surf.m_字体, text[i], rects[i].extent.x, rects[i].extent.y, 属性.m_间距);
		分配数量 += text[i].size();
	}

	if (num && 分配数量) {
		多边形绘制分配内存(surf, 分配数量);

		auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(surf.m_间接);
		auto* tranform = f_bm_ptr<mat3>(surf.m_元素变换);
		auto* color_ptr = f_bm_ptr<uvec2>(surf.m_元素颜色);
		uint32 offset = 0;


		auto 设置字符 = [&](std::u16string str, const uvec2* 纹理索引区间, S_Rect2Df rect, float32 width, const S_RGBA8UI& 颜色, E_对齐方式 对齐方式) {
			float32 h = rect.extent.y;
			vec2 pos = f_vg_lineStringDrawPos(rect, width, 对齐方式);
			
			
			float32 推进 = 0;

			uint32 字符数量 = str.size();
			if (字符数量) {
			for (uint32 i = 0; i < 字符数量; ++i) {
				int32 t = int32(str[i]);
				auto r = surf.m_字体->m_矢量文字索引区间[t];

				uint32 index = i + offset;
				indirect[index].firstInstance = 0;
				indirect[index].instanceCount = 1;

				indirect[index].firstIndex = r.x;
				indirect[index].indexCount = r.y;

				indirect[index].vertexOffset = 0;

				tranform[index] = f_math_tranform(pos, {h, h});
				pos.x += ( surf.m_字体->m_字符属性[t].horiBearingX ) * h + 属性.m_间距;

				color_ptr[index] = S_2D颜色包(颜色, 0, 0, 0);
			}
			offset += 字符数量;
			}
		};


		if (surf.m_填充面) {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字索引区间.data(), rects[i], widths[i], color[i], 对齐方式[i]);
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字边索引区间.data(), rects[i], widths[i], color[i], 对齐方式[i]);
			}
		}
	}
	else {
		多边形绘制分配内存(surf, 0);
	}
	多边形常量推送初始化(surf, &f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送));
}


void f_vg_drawStringBlock(S_Surface2D&							surf, 
					std::vector<std::u16string>					text, 
					const std::vector<S_Rect2Df>&				rects, 
					const std::vector<std::vector<S_RGBA8UI>>&	color, 
					const std::vector<E_对齐方式>&				对齐方式,
					S_字符串绘制属性 属性)
{
	uint32 num = text.size();
	std::vector<float32> widths(num);

	uint32 分配数量 = 0;
	for (uint32 i = 0; i < num; ++i) {
		widths[i] = f_vg_StringCutOut(*surf.m_字体, text[i], rects[i].extent.x, rects[i].extent.y, 属性.m_间距);
		分配数量 += text[i].size();
	}

	if (num && 分配数量) {
		多边形绘制分配内存(surf, 分配数量);

		auto* indirect	= f_bm_ptr<S_VkDrawIndexedIndirectCommand>(surf.m_间接);
		auto* tranform	= f_bm_ptr<mat3>(surf.m_元素变换);
		auto* color_ptr	= f_bm_ptr<uvec2>(surf.m_元素颜色);
		uint32 offset	= 0;


		auto 设置字符 = [&](std::u16string str, const uvec2* 纹理索引区间, S_Rect2Df rect, float32 width, const S_RGBA8UI* 颜色, E_对齐方式 对齐方式) {
			vec2 pos = f_vg_lineStringDrawPos(rect, width, 对齐方式);
			
			float32 推进 = 0;
			uint32 字符数量 = str.size();
			for (uint32 i = 0; i < 字符数量; ++i) {
				int32 t = int32(str[i]);
				auto r = surf.m_字体->m_矢量文字索引区间[t];

				uint32 index = i + offset;
				indirect[index].firstInstance = 0;
				indirect[index].instanceCount = 1;

				indirect[index].firstIndex = r.x;
				indirect[index].indexCount = r.y;

				indirect[index].vertexOffset = 0;

				tranform[index] = f_math_tranform(pos, {属性.m_字号, 属性.m_字号});
				pos.x += ( surf.m_字体->m_字符属性[t].horiBearingX ) * 属性.m_字号 + 属性.m_间距;

				color_ptr[index] = S_2D颜色包(颜色[i], 0, 0, 0);
			}
			offset += 字符数量;
		};


		if (surf.m_填充面) {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字索引区间.data(), rects[i], widths[i], color[i].data(), 对齐方式[i]);
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				设置字符(text[i], surf.m_字体->m_矢量文字边索引区间.data(), rects[i], widths[i], color[i].data(), 对齐方式[i]);
			}
		}
	}
	else {
		多边形绘制分配内存(surf, 0);
	}
	多边形常量推送初始化(surf, &f_df_推送常量<S_ConstPush_2DPolygonElement>(surf.m_常量推送));
}


float32 f_vg_getStringSize(S_Surface2D& 层, std::u16string text, float32 g, float32 间距, E_方向 方向) {
	float32 s = 0;
	int32 字符数量 = text.size();
	//float32 d = 1.0 / 64.0f;

	for (int32 i = 0; i < 字符数量; ++i) {
		s += f_vg_getCharWidth(*层.m_字体, text[i], g);
	}
	s += 间距 * max(字符数量 - 1, 0);
	return s;
}

float32 f_vg_getStringSize(const S_矢量字体& 字体, const std::u16string& str, float32 字号, float32 间距) {
	float32	s = 0;
	int32	字符数量 = str.size();
	
	for (int32 i = 0; i < 字符数量; ++i) {
		s += f_vg_getCharWidth(字体, str[i], 字号);
	}
	s += 间距 * max(字符数量 - 1, 0);
	return s;
}

//float32 f_vg_getStringSize(const S_矢量字体& 字体, const uint16 str, float32 g) {
//	return 字体.m_字符属性[str].width * g;
//}

float32 f_vg_StringCutOut(const S_矢量字体& 字体, std::u16string& str, float32 width, float32 字号, float32 间距) {
	float32 宽度 = 0;
	int32 strNum = 0;
	for (auto& e : str) {
		宽度 += f_vg_getCharWidth(字体, e, 字号) + 间距;
		++strNum;
		if (宽度 > width) {
			break;
		}
	}
	str = str.substr(0, strNum);
	return 宽度;
}

vec2 f_vg_lineStringCutOut(const S_矢量字体& 字体, std::u16string& str, S_Rect2Df rect, E_对齐方式 对齐, float32 字号, float32 间距) {
	vec2 pos = rect.offset;
	float32 width = f_vg_StringCutOut(字体, str, rect.extent.x - rect.extent.y * 0.4, 字号, 间距);

	switch (对齐) {
		case E_对齐方式::e_据中对齐:
			pos.x += (rect.extent.x - width) * 0.5;
			break;
		case E_对齐方式::e_右对齐:
			pos.x += (rect.extent.x - width);
			break;
		default:
			pos.x += rect.extent.y * 0.2;
			break;
	}
	pos.y = rect.offset.y + f_vg_StringDrawOffset(rect.extent.y);
	return pos;
}


void f_vg_drawPolygon(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[]) {
	if (num) {
		多边形绘制分配内存(层, num);

		auto* indirect = f_bm_ptr<S_VkDrawIndexedIndirectCommand>(层.m_间接);

		for (uint32 i = 0; i < num; ++i) {
			indirect[i].firstIndex = 块元素[i]->m_Mem.m_偏移;
			indirect[i].indexCount = 块元素[i]->m_Mem.m_数量;

			indirect[i].firstInstance = 0;
			indirect[i].instanceCount = 1;
			indirect[i].vertexOffset = 0;
		}
	}
	else {
		多边形绘制分配内存(层, 1);
	}

	多边形常量推送初始化(层, &f_df_推送常量<S_ConstPush_2DPolygonElement>(层.m_常量推送));
}

void f_vg_drawPolygonEffect(S_Surface2D& 层, S_GPU内存块* 块元素) {
	
}

void f_vg_setMeasure(S_2D画布* s, uint32 行文本, S_RGBA8UI color, uint32 num, const vec2* offset, const int32* 刻度, uint8 最大位数) {
	auto& 层 = *s->m_绘制元素[行文本];
	S_字符GPU参数& 参数 = *(S_字符GPU参数*)层.m_自定义属性参数;

	std::vector<int32> t;
	f_bm_resize(层.m_顶点, num);

	S_2D字符* 字符点 = f_bm_ptr<S_2D字符>(层.m_顶点);

	for (uint32 i = 0; i < num; ++i) {
		字符点[i].point = offset[i];
		字符点[i].CharOffset_Num.x = t.size();

		uint32 字符数量 = 0;
		auto str = f_整数值转宽字符串(刻度[i]);
		for (auto& s : str) {
			t.push_back(s);
			++字符数量;
		}

		字符点[i].CharOffset_Num.y = 字符数量;
		字符点[i].AA_type.x = f_PackData4X8(color);
		字符点[i].AA_type.y = 0;
	}

	f_bm_fill(参数.字符, t.data(), t.size());
}
void f_vg_text_tranform(S_2D画布* s, uint32 元素, vec2 loc, vec2 scal, vec2 rot) {
	mat3 mat = f_mat3x3_Identity();
	mat *= f_mat3x3_Location(loc);
}




//======================================== 凸包几何 ===================================================


static void f_凸包图元_着色器参数配置(S_设备环境& ctx, S_Surface2D& surf) {
	//auto* rt = f_vk_get绘图环境(ctx);
	//auto* rf = f_vk_get绘图框架(ctx);

	//auto& const_push = (*(S_2DConvexElement_PanelAttr*)surf.m_常量推送);
	auto& push = f_df_推送常量<S_2DConvexElement_PanelAttr>(surf.m_常量推送);

	push.m_Offset_TranformG = uint32(surf.m_画布变换->m_Mem.m_偏移);
	push.m_Offset_TranformL = uint32(surf.m_元素变换.m_Mem.m_偏移);
	push.m_Offset_Color = uint32(surf.m_元素颜色.m_Mem.m_偏移);
	push.m_Offset_Rect = uint32((*surf.m_自定义属性).m_Mem.m_偏移);
}

S_Surface2D* f_vg_genConvex(S_设备环境& ctx, S_2D画布& 画布, E_填充模式 填充模式, E_图层混合模式 混合模式) {
	//auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);

	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);
	surf->m_画布变换 = &画布.m_变换;

	
	if (填充模式 == E_填充模式::e_填充面) {
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_凸包图元面[混合模式];
	}
	else{
		surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_凸包图元线[混合模式];
	}
	
	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_序列元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_间接;
	
	surf->mf_参数设置回调 = f_凸包图元_着色器参数配置;
	f_df_创建常量推送<S_2DConvexElement_PanelAttr>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	

	surf->m_自定义属性 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*surf->m_自定义属性) = f_bm_alloc(ctx.m_几何图形->m_2D凸包图元属性, 1);

	return surf;
}

void f_vg_drawConvex(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[], const S_2DConvexRect* 区域, float32 线宽) {
	if (num) {
		
		f_bm_fill((*层.m_自定义属性), 区域, num);
		f_bm_resize(层.m_间接, num);
		//f_bm_resize((*层.m_自定义属性), num);
		auto* indirect = f_buf_Indirect_ptr(层.m_间接);
		//auto* rect = f_bm_ptr<S_2DConvexRect>((*层.m_自定义属性));

		for (uint32 i = 0; i < num; ++i) {
			indirect[i].firstInstance = 0;
			indirect[i].instanceCount = 1;
			indirect[i].firstVertex = 块元素[i]->m_Mem.m_偏移;
			indirect[i].vertexCount = 块元素[i]->m_Mem.m_数量;
			//rect[i] = 区域[i];
		}
	}
	else {
		f_bm_resize(层.m_间接, 0);
		f_bm_resize(*层.m_自定义属性, 0);
		//f_buf_Indirect_at(层.m_间接) = {};
		//S_2DConvexRect r{};
		//f_bm_fill((*层.m_自定义属性), &r, 0);
	}
	层.m_线宽 = 线宽;
}




//======================================== 画刻度线 ===================================================

static void f_刻度线_着色器参数配置(S_设备环境& ctx, S_Surface2D& 层) {
	//S_ConstPush_TickMark& 属性 = *(S_ConstPush_TickMark*)层.m_常量推送;
	
}

S_Surface2D* f_vg_drawTickMark(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);


	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.push_back(surf);

	//surf->m_顶点 = f_bm_alloc(f_buf_getGlobal().m_2D线, 0);
	surf->m_画布变换 = &画布.m_变换;
	
	

	f_bm_resize(surf->m_间接, 1);
	f_buf_Indirect_at(surf->m_间接) = {};

	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_刻度线[混合模式];

	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_序列元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_无顶点索引;

	surf->mf_参数设置回调 = f_刻度线_着色器参数配置;
	f_df_创建常量推送<S_ConstPush_TickMark>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	
	surf->m_线宽 = 0.5;
	return surf;
}

void f_vg_setTickMark(S_Surface2D& 层, uint32 num, vec2 跨度, vec2 size, uint32 方向) {
	
	//S_ConstPush_TickMark& 属性 = *(S_ConstPush_TickMark*)层.m_常量推送;
	auto& push = f_df_推送常量<S_ConstPush_TickMark>(层.m_常量推送);

	push.m_Offset_TranformG = 层.m_画布变换->m_Mem.m_偏移;
	push.m_Offset_TranformL = 层.m_元素变换.m_Mem.m_偏移;
	push.m_Offset_Color = 层.m_元素颜色.m_Mem.m_偏移;
	push.m_Dir = 方向;

	push.ox = 跨度.x;
	push.oy = 跨度.y;
	push.w = size.x;
	push.h = size.y;

	层.m_顶点数量 = num;

}




//======================================== 波形 ===========================================
struct S_波形图元GPU参数 {
	S_GPU内存块 波形属性;
};

static void f_波形图元_着色器参数配置(S_2D画布* 画布, S_Surface2D* 层, S_板载缓存* 视图矩阵) {
	S_波形图元GPU参数& 参数 = *((S_波形图元GPU参数*)层->m_自定义属性参数);
	//S_ConstPush_Waveform& attr = *(S_ConstPush_Waveform*)surf->m_常量推送;
	auto& push = f_df_推送常量<S_ConstPush_Waveform>(层->m_常量推送);

	层->m_多维材质槽.m_参数槽.m_参数槽[0] = 视图矩阵;
	层->m_多维材质槽.m_参数槽.m_绑定位置[0] = DEF_BINDING_PROJECT;
	层->m_多维材质槽.m_参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	层->m_多维材质槽.m_参数槽.m_绑定数量[0] = 1;

	push.m_Offset_Instance = 画布->m_变换.m_Mem.m_偏移;
	push.m_Offset_Waveform = 参数.波形属性.m_Mem.m_偏移;
	push.m_WaveformNum = 参数.波形属性.m_Mem.m_数量;
}
static void f_波形图元_销毁自定义参数(S_Surface2D* surf) {
	S_波形图元GPU参数& 参数 = *((S_波形图元GPU参数*)surf->m_自定义属性参数);
	f_bm_erase(参数.波形属性);
	f_releaseGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽);
}

uint32 f_vg_drawWaveform(S_2D画布* s) {
	S_Surface2D* surf = f_surface2D_alloc(s->m_Ctx);

	f_bm_resize(surf->m_间接, 1);
	f_buf_Indirect_at(surf->m_间接) = {};

	surf->m_多维材质槽.m_Material = s->m_调色板->m_波形_正常混合;

	surf->mf_绘制参数设置 = f_波形图元_着色器参数配置;
	surf->mf_销毁自定义参数 = f_波形图元_销毁自定义参数;

	S_波形图元GPU参数* 参数 = (S_波形图元GPU参数*)malloc(sizeof(S_波形图元GPU参数));
	参数->波形属性 = f_bm_alloc(f_buf_getGlobal().g_波形属性, 1);


	f_df_allocGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽, 3);
	surf->m_多维材质槽.m_参数槽.m_参数槽[1] = &s->m_变换;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[1] = 1;
	surf->m_多维材质槽.m_参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[1] = 1;

	surf->m_多维材质槽.m_参数槽.m_参数槽[2] = &参数->波形属性;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[2] = 2;
	surf->m_多维材质槽.m_参数槽.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[2] = 1;

	f_df_创建常量推送<S_ConstPush_Waveform>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	//(*(S_ConstPush_Waveform*)surf->m_常量推送).m_Offset_Instance = s->m_变换.m_Mem.m_偏移;


	surf->m_自定义属性参数 = 参数;
	surf->m_实例数量 = s->m_变换.m_Mem.m_数量;
	surf->m_实例偏移 = s->m_变换.m_Mem.m_偏移;
	surf->m_线宽 = 1;


	uint32 预设图元 = s->m_绘制元素.size();
	s->m_绘制元素.push_back(surf);
	return 预设图元;
}

void f_vg_setWaveformRect(S_2D画布* s, uint32 元素, S_Waveform wf, float32 weidth) {
	auto& 层 = *s->m_绘制元素[元素];
	S_波形图元GPU参数& 参数 = *(S_波形图元GPU参数*)层.m_自定义属性参数;

	wf.m_SampleOffset = {weidth - 层.m_顶点.m_Mem.m_数量 * wf.m_SampleWidth, 0};

	f_bm_at<S_Waveform>(参数.波形属性, 0) = wf;
	层.m_线宽 = 2;
}

void f_vg_setWaveform(S_2D画布* s, uint32 元素, uint32 num, const float32* point) {
	auto& 层 = *s->m_绘制元素[元素];

	num = num > 1 ? num - 1 : 0;
	f_bm_resize(层.m_顶点, num);
	if (num) {
		auto* cu = f_bm_ptr<S_2D图元顶点>(层.m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			cu[i].coord = { point[i], point[i + 1] };
			cu[i].weights.x = i;
			cu[i].weights.y = i + 1;
		}
	}
	
	auto& indirect = f_buf_Indirect_at(层.m_间接);
	indirect.firstInstance = 0;
	indirect.instanceCount = s->m_变换.m_Mem.m_数量;
	indirect.firstVertex = 层.m_顶点.m_Mem.m_偏移;
	indirect.vertexCount = 层.m_顶点.m_Mem.m_数量;

}

void f_vg_setWaveform(S_2D画布* s, uint32 元素, uint32 num, S_Waveform* wf, float32** point) {
	auto& 层 = *s->m_绘制元素[元素];
	S_波形图元GPU参数& 参数 = *(S_波形图元GPU参数*)层.m_自定义属性参数;
	层.m_线宽 = 2;

	uint32 采样点数量 = 0;
	f_bm_resize(参数.波形属性, num);
	if (num) {
		
		auto* 波形属性 = f_bm_ptr<S_Waveform>(参数.波形属性);
		for (uint32 i = 0; i < num; ++i) {
			波形属性[i] = wf[i];
			采样点数量 += wf[i].m_SampleNum;
		}

	}
	

	if (采样点数量) {
		f_bm_resize(层.m_间接, num);
		f_bm_resize(层.m_顶点, 采样点数量);



		uint32 顶点偏移 = 层.m_顶点.m_Mem.m_偏移;

		auto* cu = f_bm_ptr<S_2D图元顶点>(层.m_顶点);

		uint32 offset = 0;
		for (uint32 i = 0; i < num; ++i) {
			uint32 波形点数量 = wf[i].m_SampleNum;
			波形点数量 = 波形点数量 > 1 ? 波形点数量 - 1 : 0;

			for (uint32 s = 0; s < 波形点数量; ++s) {
				cu[offset].coord = { point[i][s], point[i][s + 1] };
				cu[offset].weights.x = s;
				cu[offset].weights.y = s + 1;

				++offset;
			}


			auto& indirect = f_buf_Indirect_at(层.m_间接, i);
			indirect.firstInstance = 0;
			indirect.instanceCount = s->m_变换.m_Mem.m_数量;
			indirect.firstVertex = 顶点偏移;
			indirect.vertexCount = 波形点数量;

			顶点偏移 += 波形点数量;
		}
	}
	else {
		f_bm_resize(层.m_间接, 1);

		auto& indirect = f_buf_Indirect_at(层.m_间接, 0);
		indirect.firstInstance = 0;
		indirect.instanceCount = s->m_变换.m_Mem.m_数量;
		indirect.firstVertex = 0;
		indirect.vertexCount = 0;
	}
}



//========================================= 纹理图像 ==========================================

struct S_纹理图像GPU参数 {
	S_GPU内存块 m_区域;
	S_GPU内存块 m_纹理ID;
	S_纹理*		m_单纹理;
};

static void f_纹理图像_着色器参数配置(S_2D画布* 画布, S_Surface2D* surf, S_板载缓存* 视图矩阵) {
	S_纹理图像GPU参数& 参数 = *((S_纹理图像GPU参数*)surf->m_自定义属性参数);

	surf->m_多维材质槽.m_参数槽.m_参数槽[0] = 视图矩阵;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[0] = DEF_BINDING_PROJECT;
	surf->m_多维材质槽.m_参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[0] = 1;

	surf->m_多维材质槽.m_参数槽.m_参数槽[2] = &参数.m_区域;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[2] = 2;
	surf->m_多维材质槽.m_参数槽.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[2] = 1;

	surf->m_多维材质槽.m_参数槽.m_参数槽[3] = &参数.m_纹理ID;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[3] = 3;
	surf->m_多维材质槽.m_参数槽.m_参数类型[3] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[3] = 1;

	surf->m_多维材质槽.m_参数槽.m_参数槽[4] = 参数.m_单纹理;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[4] = 11;
	surf->m_多维材质槽.m_参数槽.m_参数类型[4] = E_板载缓存类型::e_IMAGE_SAMPLER;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[4] = 1;

	//(*(S_ConstPush_Textures*)surf->m_常量推送).m_Offset_Instance = 画布->m_变换.m_Mem.m_偏移;
	//(*(S_ConstPush_Textures*)surf->m_常量推送).m_Offset_Rect = 参数.m_区域.m_Mem.m_偏移;
	//(*(S_ConstPush_Textures*)surf->m_常量推送).m_Offset_TextureAtt = 参数.m_纹理ID.m_Mem.m_偏移;
}

static void f_纹理图像_销毁自定义参数(S_Surface2D* surf) {
	//S_纹理图像GPU参数& 参数 = *((S_纹理图像GPU参数*)surf->m_参数);
	free(surf->m_自定义属性参数);
	f_releaseGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽);
}

uint32 f_vg_drawTextures(S_2D画布* s, E_纹理类型 纹理类型, E_图层混合模式 混合模式) {
	S_Surface2D* surf = f_surface2D_alloc(s->m_Ctx);

	surf->m_顶点引用 = true;
	surf->m_顶点 = S_2D画布::g预设_矩形;
	f_bm_resize(surf->m_间接, 1);
	f_buf_Indirect_at(surf->m_间接) = {};
	
	surf->mf_绘制参数设置 = f_纹理图像_着色器参数配置;
	surf->mf_销毁自定义参数 = f_纹理图像_销毁自定义参数;


	surf->m_纹理槽 = f_纹理槽_创建(1);
	f_纹理槽_设置纹理(surf->m_纹理槽, S_全局缓存::g_空纹理, DEF_BINDING_WIDGET_Texture, 0);

	f_df_allocGPU参数缓存槽(&surf->m_多维材质槽.m_参数槽, 5);
	surf->m_多维材质槽.m_参数槽.m_参数槽[1] = &s->m_变换;
	surf->m_多维材质槽.m_参数槽.m_绑定位置[1] = 1;
	surf->m_多维材质槽.m_参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	surf->m_多维材质槽.m_参数槽.m_绑定数量[1] = 1;

	surf->m_多维材质槽.m_参数槽.m_纹理槽 = &(surf->m_纹理槽);



	S_纹理图像GPU参数* 参数 = (S_纹理图像GPU参数*)malloc(sizeof(S_纹理图像GPU参数));
	参数->m_纹理ID = f_bm_alloc(f_buf_getGlobal().m_UI32动态属性, 1);
	参数->m_区域 = f_bm_alloc(f_buf_getGlobal().g_凸包图元区域, 1);
	参数->m_单纹理 = f_buf_getGlobal().g_空纹理;


	f_df_创建常量推送<S_ConstPush_Textures>(surf->m_常量推送, E_着色阶段::e_顶点着色);


	
	surf->m_自定义属性参数 = 参数;
	surf->m_线宽 = 1;
	surf->m_实例数量 = s->m_变换.m_Mem.m_数量;
	surf->m_实例偏移 = s->m_变换.m_Mem.m_偏移;

	uint32 预设图元 = s->m_绘制元素.size();
	s->m_绘制元素.push_back(surf);
	return 预设图元;
}

void f_vg_setTextureRect(S_2D画布* s, uint32 元素, uint32 num, const S_GPU内存块* const* 块元素, const S_2DConvexRect* rect, const uint32* texID) {
	auto& 层 = *s->m_绘制元素[元素];

	if (num) {
		S_纹理图像GPU参数& 参数 = *(S_纹理图像GPU参数*)层.m_自定义属性参数;

		f_gbuf_fill(参数.m_区域, rect, 0, num);

		f_bm_resize(层.m_间接, num);
		auto* indirect = f_buf_Indirect_ptr(层.m_间接);

		f_bm_resize(参数.m_纹理ID, num);
		auto* 纹理属性 = f_bm_ptr<uint32>(参数.m_纹理ID);

		for (uint32 i = 0; i < num; ++i) {
			indirect[i].firstInstance = 0;
			indirect[i].instanceCount = s->m_变换.m_Mem.m_数量;
			indirect[i].firstVertex = 块元素[i]->m_Mem.m_偏移;
			indirect[i].vertexCount = 块元素[i]->m_Mem.m_数量;

			纹理属性[i] = texID[i];
		}
	}
	else {
		f_bm_resize(层.m_间接, 1);
		f_buf_Indirect_at(层.m_间接) = {};
	}
}

void f_vg_setTextures(S_2D画布* s, uint32 元素, uint32 num, S_纹理集** tex, uint16 绘制类型, uint16 纹理类型) {
	auto& 层 = *s->m_绘制元素[元素];
	//(*(S_ConstPush_Textures*)层.m_常量推送).m_DrawType = (纹理类型<<16) | 绘制类型;

	switch (纹理类型) {
		case DEF_ObType_SamplerType_None:
			assert(0);
			break;
		case DEF_ObType_SamplerType_2DArray:
			f_纹理槽_填充纹理集(层.m_纹理槽, num, tex, DEF_BINDING_WIDGET_Texture);
			break;
		case DEF_ObType_SamplerType_CubeArray:
			f_纹理槽_填充纹理集(层.m_纹理槽, num, tex, 12);
			break;
		default:
			break;
	}
}

void f_vg_setTexture(S_2D画布* s, uint32 元素, uint32 num, S_纹理* tex, uint16 绘制类型) {
	auto& 层 = *s->m_绘制元素[元素];

	S_纹理图像GPU参数& 参数 = *((S_纹理图像GPU参数*)层.m_自定义属性参数);

	//(*(S_ConstPush_Textures*)层.m_常量推送).m_DrawType = DEF_ObType_SamplerType_None<<16 | 绘制类型;
	参数.m_单纹理 = tex;
}


static void f_textures_着色器参数配置(S_设备环境& ctx, S_Surface2D& 层) {
	//auto& const_push = (*(S_ConstPush_Textures*)surf.m_常量推送);
	auto& push = f_df_推送常量<S_ConstPush_Textures>(层.m_常量推送);

	push.m_Offset_TranformG = uint32(层.m_画布变换->m_Mem.m_偏移);
	push.m_Offset_TranformL = uint32(层.m_元素变换.m_Mem.m_偏移);
	push.m_Offset_Rect = uint32((*层.m_自定义属性).m_Mem.m_偏移);
	push.m_Offset_Color = uint32(层.m_元素颜色.m_Mem.m_偏移);
}

S_Surface2D* f_vg_genTextures(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式) {
	auto* rt = f_vk_get绘图环境(ctx);

	S_Surface2D* surf = f_surface2D_alloc(ctx);
	画布.m_绘制元素.emplace_back(surf);
	surf->m_画布变换 = &画布.m_变换;


	surf->m_多维材质槽.m_Material = rt->m_2D渲染管线->m_管线_纹理图像[混合模式];

	surf->m_间接 = f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_序列元素, 1);
	surf->m_元素变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换L, 1);
	surf->m_元素颜色 = f_bm_alloc(ctx.m_几何图形->m_2D面板颜色, 1);
	surf->m_绘制类型 = S_元素绘制类型::e_绘制类型_间接;

	surf->mf_参数设置回调 = f_textures_着色器参数配置;
	f_df_创建常量推送<S_ConstPush_Textures>(surf->m_常量推送, E_着色阶段::e_顶点着色);
	
	surf->m_自定义属性 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
	(*surf->m_自定义属性) = f_bm_alloc(ctx.m_几何图形->m_2D凸包图元属性, 1);

	return surf;
}

void f_vg_setTextures(S_Surface2D& 层, uint32 num, const S_2DConvexRect* 区域, S_GPU内存块* 形状[]) {
	if (num) {
		f_bm_fill((*层.m_自定义属性), 区域, num);
		
		f_bm_resize(层.m_间接, num);
		auto* indirect = f_buf_Indirect_ptr(层.m_间接);
		
		for (uint32 i = 0; i < num; ++i) {
			indirect[i].firstInstance = 0;
			indirect[i].instanceCount = 1;
			indirect[i].firstVertex = 形状[i]->m_Mem.m_偏移;
			indirect[i].vertexCount = 形状[i]->m_Mem.m_数量;
		}
	}
	else {
		f_bm_resize(层.m_间接, 1);
		f_buf_Indirect_at(层.m_间接) = {};
		S_2DConvexRect r{};
		f_bm_fill((*层.m_自定义属性), &r, 1);
	}
}



//废弃


//uint16 f_vg_画图标(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元) {
//	if (是否开始新图元) f_vg_记录图元(s, 笔刷.m_材质);
//	s->m_surf[s->m_绘制推进层].m_顶点数量 = 1;
//	return s->m_绘制推进层;
//	
//}



/*uint16 f_vg_绘制圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否填充, float32 半径, float32 线宽, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.m_材质);



	if (是否填充) {
		std::vector<S_2D元素顶点> vert;
		f_构建圆角矩形顶点(vert, 半径);
		//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);

		f_buf_gresize(s->m_surf[s->m_绘制推进层].m_顶点, vert.size());
		auto* 圆角矩形 = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
		for (uint32 i = 0; i < vert.size(); ++i) {
			圆角矩形[i].coord = vert[i].coord;
			圆角矩形[i].weights = vert[i].weights;
		}
	}
	else {
		std::vector<S_2D图元顶点> vert;
		f_构建圆角矩形顶点(vert, 半径, false);
		vert.insert(vert.begin(), vert.back());
		vert.push_back(vert[1]);
		vert.push_back(vert[2]);
		//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);
		f_buf_gresize(s->m_surf[s->m_绘制推进层].m_顶点, vert.size());
		auto* 圆角矩形 = f_buf_图元顶点_ptr(s->m_surf[s->m_绘制推进层].m_顶点);
		for (uint32 i = 0; i < vert.size(); ++i) {
			圆角矩形[i].coord = vert[i].coord;
			圆角矩形[i].weights = vert[i].weights;
		}
	}

	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点.m_Mem.m_大小;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}*/



/*uint16 f_vg_绘制半圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, float32 半径, E_方向 方向, bool 是否填充, float32 线宽) {
	//f_vg_记录图元(s);
	f_vg_记录图元(s, 笔刷.m_材质);


	//uint32 num = f_构建圆角矩形顶点(园圈点, 1.0, false);
	uint32 num = DEF_Max(3, uint32(DEF_Max(半径, 8) / 2)) * 2;

	std::vector<vec2> temp(num * 4);
	f_graph_计算圆坐标XY({ 0.5, 0.5 }, 0.5, num * 4, temp.data());


	if (是否填充) {
		std::vector<S_2D元素顶点> vert;
		switch (方向)
		{
		case E_方向::e_左: {
			//第三现象
			for (uint32 i = num; i <= num * 2; ++i) {
				vert.push_back({ temp[i], {0,1} });
			}
			//第二象限
			for (uint32 i = num * 2; i <= num * 3; ++i) {
				vert.push_back({ temp[i], {0,0} });
			}

			vert.push_back({ {1.0f, 0.0f}, {1,0} });
			vert.push_back({ {1.0f, 1.0f}, {1,1} });

			break;
		}
		case E_方向::e_右: {


			//第四象限
			for (uint32 i = 0; i <= num; ++i) {
				vert.push_back({ temp[i], {1,1} });
			}

			vert.push_back({ {0.0f, 1.0f}, {0,1} });
			vert.push_back({ {0.0f, 0.0f}, {0,0} });

			//第二现象
			for (uint32 i = num * 3; i < num * 4; ++i) {
				vert.push_back({ temp[i], {1,0} });
			}
			vert.push_back({ temp[0], {1,0} });

		}
		default:
			break;
		}

		f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);
	}
	else {
		std::vector<S_2D图元顶点> vert;
		switch (方向)
		{
		case E_方向::e_左: {
			//第三现象
			for (uint32 i = num; i <= num * 2; ++i) {
				vert.push_back({ temp[i], {0,1} });
			}
			//第二象限
			for (uint32 i = num * 2; i <= num * 3; ++i) {
				vert.push_back({ temp[i], {0,0} });
			}

			vert.push_back({ {1.0f, 0.0f}, {0,0} });
			vert.push_back({ {1.0f, 1.0f}, {0,0} });

			break;
		}
		case E_方向::e_右: {
			//第四象限
			for (uint32 i = 0; i <= num; ++i) {
				vert.push_back({ temp[i], {1,1} });
			}

			vert.push_back({ {0.0f, 1.0f}, {0,1} });
			vert.push_back({ {0.0f, 0.0f}, {0,0} });

			//第一现象
			for (uint32 i = num * 4; i < num * 4; ++i) {
				vert.push_back({ temp[i], {1,0} });
			}
			vert.push_back({ temp[0], {1,0} });

		}
		default:
			break;
		}

		f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);
	}


	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点->m_Size;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}*/






/*uint16 f_vg_绘制多单元圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, uint16 单元数量, float32 半径, E_方向 dir, float32 线宽, bool 是否开始新图元) {
	//if (是否开始新图元) f_vg_记录图元(s);
	if (是否开始新图元) f_vg_记录图元(s, 笔刷.m_材质);


	std::vector<S_2D图元顶点> vert;
	f_构建圆角矩形顶点(vert, 半径, false);
	vert.insert(vert.begin(), vert.back());
	vert.push_back(vert[1]);
	vert.push_back(vert[2]);


	auto index = range<uint16>(0, vert.size());
	//index.push_back(0xffff);
	uint16 offset = vert.size();

	float32 宽度 = (1.0) / 单元数量;
	--单元数量;
	//vert.resize(offset + 单元数量 * 2);


	for (uint16 i = 0; i < 单元数量; ++i) {
		index.push_back(0xffff);

		S_2D图元顶点 v1, v2;

		if (dir == E_方向::e_横向) {
			v1.coord.x = 宽度 * (i + 1);
			v1.coord.y = 0.0;

			v2.coord.x = 宽度 * (i + 1);
			v2.coord.y = 1.0;
		}
		else {
			v1.coord.x = 0;
			v1.coord.y = 宽度 * (i + 1);

			v2.coord.x = 1.0;
			v2.coord.y = 宽度 * (i + 1);
		}


		v1.weights = v1.coord;
		v2.weights = v2.coord;


		index.push_back(vert.size());
		vert.push_back(v1);
		index.push_back(vert.size());
		vert.push_back(v2);

	}

	f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);
	f_buf_push_back(s->m_surf[s->m_绘制推进层].m_索引, index);

	s->m_surf[s->m_绘制推进层].m_顶点数量 = index.size();
	//s->m_surf[s->m_绘制推进层].m_着色参数 = 笔刷.m_GPU参数set;
	//s->m_surf[s->m_绘制推进层].m_Material = 笔刷.m_材质;
	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;

	return s->m_绘制推进层;
}

uint16 f_vg_绘制多单元圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, uint16 单元数量, E_方向 方向, float32 线宽) {
	//f_vg_记录图元(s);
	f_vg_记录图元(s, 笔刷.m_材质);

	std::vector<S_2D图元顶点> vert;
	std::vector<S_VkDrawIndirectCommand> Indirect(3);


	uint32 num = 6;
	std::vector<vec2> temp(num * 4);
	f_graph_计算圆坐标XY({ 0.5, 0.5 }, 0.5, num * 4, temp.data());


	//std::vector<S_2D线图元顶点> vert;
	switch (方向)
	{
	case E_方向::e_横向: {
		//================== 左边 =====================
		//第三现象
		for (uint32 i = num; i <= num * 2; ++i) {
			vert.push_back({ temp[i], {0,1}, {} });
		}
		//第二象限
		for (uint32 i = num * 2; i <= num * 3; ++i) {
			vert.push_back({ temp[i], {0,0}, {} });
		}

		vert.push_back({ {1.0f, 0.0f}, {0,0}, {} });
		vert.push_back({ {1.0f, 1.0f}, {0,0}, {} });

		Indirect[0] = { uint32(vert.size()), 1, 0, 0 };
		Indirect[0] = { uint32(vert.size()), 1, uint32(vert.size()), 0 };
		Indirect[0] = { 4, 1, uint32(vert.size()*2), 0 };



		//================= 右边 ====================
		//第四象限
		for (uint32 i = 0; i <= num; ++i) {
			vert.push_back({ temp[i], {1,1}, {} });
		}

		vert.push_back({ {0.0f, 1.0f}, {0,1}, {} });
		vert.push_back({ {0.0f, 0.0f}, {0,0}, {} });

		//第一现象
		for (uint32 i = num * 4; i < num * 4; ++i) {
			vert.push_back({ temp[i], {1,0}, {} });
		}
		vert.push_back({ temp[0], {1,0}, {} });


		//================= 中间 ===================
		vert.push_back({ {0.0f, 0.0f}, {0,0}, {} });
		vert.push_back({ {1.0f, 0.0f}, {1,0}, {} });
		vert.push_back({ {1.0f, 1.0f}, {1,1}, {} });
		vert.push_back({ {0.0f, 1.0f}, {0,1}, {} });

		break;
	}
	case E_方向::e_纵向: {

		break;
	}
	default:
		break;
	}

	f_buf_fill板载缓存(s->m_surf[s->m_绘制推进层].m_顶点, vert);
	//f_buf_push_back(s->m_surf[s->m_绘制推进层].m_顶点, vert);
	f_buf_fill板载缓存(s->m_surf[s->m_绘制推进层].m_间接, Indirect);


	//s->m_surf[s->m_绘制推进层].m_类型数量 = 3;
	s->m_surf[s->m_绘制推进层].m_顶点数量 = s->m_surf[s->m_绘制推进层].m_顶点->m_Size;

	s->m_surf[s->m_绘制推进层].m_线宽 = 线宽;
	return s->m_绘制推进层;
}*/


/*void f_vg_add绘制线(S_2D画布* s, uint16 id, vec2* point, uint32 num) {
	std::vector<S_2D图元顶点> data(num);
	for (uint32 i = 0; i < num; ++i) {
		data[i] = { point[i], {1.0f,1.0f}, {0,0} };
	}
	f_buf_push_back(s->m_surf[id].m_顶点, data);
}*/




/*inline uint32 f_构建圆角矩形顶点(std::vector<S_2D元素顶点>& vert, float32 半径) {
	uint32 num = uint32(DEF_Max(半径, 8) / 2) * 2;
	std::vector<vec2> temp(num);
	f_计算圆坐标2({ 0.0, 0.0 }, 0.5, num, temp.data());
	temp.push_back(temp.front());

	uint32 n = num / 4;
	uint32 圆角点数量 = (n + 1);

	vert.resize(圆角点数量 * 4);

	//vert.resize(圆角点数量 * 4);
	for (uint32 i = 0; i < 圆角点数量; ++i) {
		vert[i * 2].coord = temp[i] + 0.5;
		vert[i * 2 + 1].coord = temp[n * 4 - i] + 0.5;

		vert[i * 2 + 圆角点数量 * 2].coord = temp[n + i] + 0.5;
		vert[i * 2 + 圆角点数量 * 2 + 1].coord = temp[n * 3 - i] + 0.5;
	}


	for (uint32 i = 0; i < 圆角点数量; ++i) {
		vert[i * 2].weights = { 1.0f, 1.0f };
		vert[i * 2 + 1].weights = { 0.0, 1.0 };
		vert[i * 2 + 圆角点数量 * 2].weights = { 1.0, 0.0 };
		vert[i * 2 + 圆角点数量 * 2 + 1].weights = { 0.0,0.0 };
	}



	return 圆角点数量;
}*/






//uint16 f_vg_gen顶点(S_2D画布* s, uint32 num) {
//	S_板载缓存* mat = f_buf_create板载缓存(s->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(mat3X2));
//	std::vector<mat3X2> data(DEF_Max(1, num));
//	f_buf_fill板载缓存<mat3X2>(mat, data, E_板载缓存类型::e_SSBO);
//	s->m_扩展GPU参数.push_back(mat);
//
//	if (!num) {
//		mat->m_Size = 0;
//	}
//
//	return s->m_扩展GPU参数.size() - 1;
//}

//uint16 f_vg_gen图元(S_2D画布* s, uint32 num) {
//	S_板载缓存* mat = f_buf_create板载缓存(s->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(uvec2));
//	std::vector<uvec2> data(DEF_Max(1, num));
//	f_buf_fill板载缓存<uvec2>(mat, data, E_板载缓存类型::e_SSBO);
//	s->m_扩展GPU参数.push_back(mat);
//
//	if (!num) {
//		mat->m_Size = 0;
//	}
//
//	return s->m_扩展GPU参数.size() - 1;
//}


/*S_凸边图元 f_vg_gen凸边填充图元(S_2D画布* s, const S_凸边图元& 链接元素) {
S_凸边图元 图元;

if (链接元素.属性) {
图元.属性 = 链接元素.属性;
图元.链接属性 = true;
}
else {
图元.属性 = f_vg_gen属性(s->m_Ctx);
图元.链接属性 = false;
}

if (链接元素.变换) {
图元.变换 = 链接元素.变换;
图元.链接变换 = true;
}
else {
图元.变换 = f_vg_gen2D变换(s);
图元.链接变换 = false;
}

if (链接元素.颜色) {
图元.颜色 = 链接元素.颜色;
图元.链接颜色 = true;
}
else {
图元.颜色 = f_vg_gen2D颜色(s);
图元.链接颜色 = false;
}

图元.线属性 = nullptr;
return 图元;
}*/


/*S_GPU内存块索引* f_vg_gen2D颜色2(S_2D画布* s, uint32 num) {
S_GPU内存块索引* 块 = (S_GPU内存块索引*)malloc(sizeof(S_GPU内存块索引));
(*块) = f_buf_alloc(S_2D画布::g凸包颜色2, 1);
return 块;
}*/

/*S_板载缓存* f_vg_gen图元ID(S_2D画布* s) {
S_板载缓存* 图元 = f_buf_create板载缓存(s->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(uvec2));
std::vector<uvec2> data(1);
f_buf_fill板载缓存<uvec2>(图元, data, E_板载缓存类型::e_SSBO);
s->m_扩展GPU参数.push_back(图元);

图元->m_Size = 0;

return 图元; 
}*/

/*uint16 f_vg_gen间接图元(S_2D画布* s, uint32 num)
{
S_板载缓存* 颜色 = f_create板载缓存(s->m_Ctx, sizeof(uint32));
std::vector<uint32> data(DEF_Max(1, num));
f_fill板载缓存<uint32>(颜色, data, E_板载缓存类型::e_SSBO);
s->m_扩展GPU参数.push_back(颜色);
if (!num) {
颜色->m_Size = 0;
}
return s->m_扩展GPU参数.size() - 1;
}*/

/*uint16 f_vg_gen线属性(S_2D画布* s) {
S_板载缓存* mat = f_buf_create板载缓存(s->m_Ctx, sizeof(S_线属性), E_板载缓存类型::e_SSBO);
S_线属性 data = { 0.0f, 0xffffffff, 0xffffffff };
f_buf_fill板载缓存(mat, sizeof(S_线属性), 1, &data, E_板载缓存类型::e_SSBO);
s->m_扩展GPU参数.push_back(mat);

return s->m_扩展GPU参数.size() - 1;
}*/





//S_2D笔刷 f_vg_gen图标笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 UV, std::string group) {
//	f_vg_记录图元(s, s->m_调色板->m_单色图标笔刷);
//	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
//	{
//		e.m_参数元素数量 = 3;
//		e.m_参数元素 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
//		e.m_GPU绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
//		
//		if (s->m_父级画布属性) e.m_参数元素[0] = s->m_父级画布属性;
//		else e.m_参数元素[0] = s->m_属性[属性];
//		//e.m_参数元素[0] = s->m_属性[属性];
//		e.m_参数元素[1] = s->m_扩展GPU参数[变换];
//		e.m_参数元素[2] = s->m_扩展GPU参数[颜色];
//		//e.m_参数元素[3] = s->m_扩展GPU参数[UV];
//		e.m_GPU绑定位置[0] = DEF_BINDING_WIDGET_PROP;
//		e.m_GPU绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
//		e.m_GPU绑定位置[2] = DEF_BINDING_WIDGET_Color;
//		//e.m_GPU绑定位置[3] = 3;
//
//		
//		e.m_纹理参数 = (S_纹理**)calloc(1, sizeof(S_纹理*));
//		//e.m_纹理参数数量 = 1;
//
//		e.m_纹理参数[0] = s->m_调色板->m_ICOs[group].m_Tex;
//		//e.m_纹理库对象 = group;
//		//e.m_纹理库对象 = &(s->m_调色板->m_ICOs[group]);
//		if (e.m_纹理参数[0]) {
//			e.m_纹理参数数量 = 1;
//		} else e.m_纹理参数数量 = 0;
//
//		s->m_surf[s->m_绘制推进层].m_纹理 = group;
//	}
//
//	return e;
//}

//S_2D笔刷 f_vg_gen纯纹理图标笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 UV, std::string group) {
//	f_vg_记录图元(s, s->m_调色板->m_纯纹理图标笔刷);
//	auto& e = s->m_surf[s->m_绘制推进层].m_笔刷;
//	{
//		e.m_参数元素数量 = 3;
//		e.m_参数元素 = (S_板载缓存**)calloc(e.m_参数元素数量, sizeof(S_板载缓存*));
//		e.m_GPU绑定位置 = (uint8*)calloc(e.m_参数元素数量, sizeof(uint8));
//		
//		if (s->m_父级画布属性) e.m_参数元素[0] = s->m_父级画布属性;
//		else e.m_参数元素[0] = s->m_属性[属性];
//		e.m_GPU绑定位置[0] = DEF_BINDING_WIDGET_PROP;
//		//e.m_参数元素[0] = s->m_属性[属性];
//		e.m_参数元素[1] = s->m_扩展GPU参数[变换];
//		e.m_GPU绑定位置[1] = DEF_BINDING_WIDGET_MATRIX;
//
//		e.m_参数元素[2] = s->m_扩展GPU参数[颜色];
//		e.m_GPU绑定位置[2] = DEF_BINDING_WIDGET_Color;
//
//		//e.m_参数元素[3] = s->m_扩展GPU参数[UV];
//		//e.m_GPU绑定位置[3] = 4;
//
//
//		e.m_纹理参数 = (S_纹理**)calloc(1, sizeof(S_纹理*));
//		//e.m_纹理参数数量 = 1;
//		e.m_纹理参数[0] = s->m_调色板->m_ICOs[group].m_Tex;
//		//e.m_纹理库对象 = group;
//
//		if (e.m_纹理参数[0]) {
//			e.m_纹理参数数量 = 1;
//		} else e.m_纹理参数数量 = 0;
//
//		s->m_surf[s->m_绘制推进层].m_纹理 = group;
//	}
//	return e;
//}



